def __init__(self, parent, im_gens, check=True): """ EXAMPLES:: sage: L = LieAlgebra(QQ, 'x,y,z') sage: Lyn = L.Lyndon() sage: H = L.Hall() sage: phi = Lyn.coerce_map_from(H) We skip the category test because the Homset's element class does not match this class:: sage: TestSuite(phi).run(skip=['_test_category']) """ Morphism.__init__(self, parent) if not isinstance(im_gens, Sequence_generic): if not isinstance(im_gens, (tuple, list)): im_gens = [im_gens] im_gens = Sequence(im_gens, parent.codomain(), immutable=True) if check: if len(im_gens) != len(parent.domain().lie_algebra_generators()): raise ValueError("number of images must equal number of generators") # TODO: Implement a (meaningful) _is_valid_homomorphism_() #if not parent.domain()._is_valid_homomorphism_(parent.codomain(), im_gens): # raise ValueError("relations do not all (canonically) map to 0 under map determined by images of generators.") if not im_gens.is_immutable(): import copy im_gens = copy.copy(im_gens) im_gens.set_immutable() self._im_gens = im_gens
def __init__(self, homset, imgs, check=True): r""" Constructor method. TESTS: The following input does not define a valid group homomorphism:: sage: from sage.groups.abelian_gps.abelian_group_gap import AbelianGroupGap sage: A = AbelianGroupGap([2]) sage: G = MatrixGroup([Matrix(ZZ, 2, [0,1,-1,0])]) sage: A.hom([G.gen(0)]) Traceback (most recent call last): ... ValueError: images do not define a group homomorphism """ from sage.libs.gap.libgap import libgap Morphism.__init__(self, homset) dom = homset.domain() codom = homset.codomain() gens = [x.gap() for x in dom.gens()] imgs = [codom(x).gap() for x in imgs] if check: if not len(gens) == len(imgs): raise ValueError("provide an image for each generator") self._phi = libgap.GroupHomomorphismByImages( dom.gap(), codom.gap(), gens, imgs) # if it is not a group homomorphism, then # self._phi is the gap boolean fail if self._phi.is_bool(): # check we did not fail raise ValueError("images do not define a group homomorphism") else: ByImagesNC = libgap.function_factory("GroupHomomorphismByImagesNC") self._phi = ByImagesNC(dom.gap(), codom.gap(), gens, imgs)
def __init__(self, homset, gap_hom, check=True): r""" Constructor method. TESTS:: sage: G = GL(2, ZZ) sage: H = GL(2, GF(2)) sage: P = Hom(G, H) sage: gen1 = [g.gap() for g in G.gens()] sage: gen2 = [H(g).gap() for g in G.gens()] sage: phi = G.gap().GroupHomomorphismByImagesNC(H,gen1, gen2) sage: phi = P.element_class(P,phi) sage: phi(G.gen(0)) [0 1] [1 0] """ if check: if not gap_hom.IsGroupHomomorphism(): raise ValueError("not a group homomorphism") if homset.domain().gap() != gap_hom.Source(): raise ValueError("domains do not agree") if homset.codomain().gap() != gap_hom.Range(): raise ValueError("ranges do not agree") Morphism.__init__(self, homset) self._phi = gap_hom
def __init__(self, relations, base_ring_images, images, codomain, reduce = True) : r""" INPUT: - ``relations`` -- An ideal in a polynomial ring. - ``base_ring_images`` -- A list or sequence of elements of a ring of (equivariant) monoid power series. - ``images`` -- A list or sequence of monoid power series. - ``codomain`` -- An ambient of (equivariant) monoid power series. - ``reduce`` -- A boolean (default: ``True``); If ``True`` polynomials will be reduced before the substitution is carried out. TESTS:: sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import * sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import * sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import * sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import * sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_functor import * sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False)) sage: ev = GradedExpansionEvaluationHomomorphism(PolynomialRing(QQ, ['a', 'b']).ideal(0), Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), mps, False) """ self.__relations = relations self.__base_ring_images = base_ring_images self.__images = images self.__reduce = reduce Morphism.__init__(self, relations.ring(), codomain) self._repr_type_str = "Evaluation homomorphism from %s to %s" % (relations.ring(), codomain)
def __init__(self, parent, im_gens, check=True): """ EXAMPLES:: sage: L = LieAlgebra(QQ, 'x,y,z') sage: Lyn = L.Lyndon() sage: H = L.Hall() sage: phi = Lyn.coerce_map_from(H) We skip the category test because the Homset's element class does not match this class:: sage: TestSuite(phi).run(skip=['_test_category']) """ Morphism.__init__(self, parent) if not isinstance(im_gens, Sequence_generic): if not isinstance(im_gens, (tuple, list)): im_gens = [im_gens] im_gens = Sequence(im_gens, parent.codomain(), immutable=True) if check: if len(im_gens) != len(parent.domain().lie_algebra_generators()): raise ValueError("number of images must equal number of generators") # TODO: Implement a (meaningful) _is_valid_homomorphism_() #if not parent.domain()._is_valid_homomorphism_(parent.codomain(), im_gens): # raise ValueError("relations do not all (canonically) map to 0 under map determined by images of generators.") if not im_gens.is_immutable(): import copy im_gens = copy.copy(im_gens) im_gens.set_immutable() self.__im_gens = im_gens
def __init__(self, domain, codomain): """ The Python constructor EXAMPLES:: sage: R = QQ['x']['y']['s','t']['X'] sage: p = R.random_element() sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: g = f.section() sage: g(f(p)) == p True :: sage: R = QQ['a','b','x','y'] sage: S = ZZ['a','b']['x','z'] sage: from sage.rings.polynomial.flatten import UnflatteningMorphism sage: UnflatteningMorphism(R, S) Traceback (most recent call last): ... ValueError: rings must have same base ring :: sage: R = QQ['a','b','x','y'] sage: S = QQ['a','b']['x','z','w'] sage: from sage.rings.polynomial.flatten import UnflatteningMorphism sage: UnflatteningMorphism(R, S) Traceback (most recent call last): ... ValueError: rings must have the same number of variables """ if not is_MPolynomialRing(domain): raise ValueError("domain should be a multivariate polynomial ring") if not is_PolynomialRing(codomain) and not is_MPolynomialRing( codomain): raise ValueError("codomain should be a polynomial ring") ring = codomain intermediate_rings = [] while True: is_polynomial_ring = is_PolynomialRing(ring) if not (is_polynomial_ring or is_MPolynomialRing(ring)): break intermediate_rings.append((ring, is_polynomial_ring)) ring = ring.base_ring() if domain.base_ring() != intermediate_rings[-1][0].base_ring(): raise ValueError("rings must have same base ring") if domain.ngens() != sum([R.ngens() for R, _ in intermediate_rings]): raise ValueError("rings must have the same number of variables") self._intermediate_rings = intermediate_rings hom = Homset(domain, codomain, base=ring, check=False) Morphism.__init__(self, hom) self._repr_type_str = 'Unflattening'
def __init__(self, relations, base_ring_images, images, codomain, reduce=True): r""" INPUT: - ``relations`` -- An ideal in a polynomial ring. - ``base_ring_images`` -- A list or sequence of elements of a ring of (equivariant) monoid power series. - ``images`` -- A list or sequence of monoid power series. - ``codomain`` -- An ambient of (equivariant) monoid power series. - ``reduce`` -- A boolean (default: ``True``); If ``True`` polynomials will be reduced before the substitution is carried out. TESTS:: sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import * sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import * sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import * sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import * sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_functor import * sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False)) sage: ev = GradedExpansionEvaluationHomomorphism(PolynomialRing(QQ, ['a', 'b']).ideal(0), Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), mps, False) """ self.__relations = relations self.__base_ring_images = base_ring_images self.__images = images self.__reduce = reduce Morphism.__init__(self, relations.ring(), codomain) self._repr_type_str = "Evaluation homomorphism from %s to %s" % ( relations.ring(), codomain)
def __init__(self, domain, codomain): """ The Python constructor EXAMPLES:: sage: R = QQ['x']['y']['s','t']['X'] sage: p = R.random_element() sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: g = f.section() sage: g(f(p)) == p True :: sage: R = QQ['a','b','x','y'] sage: S = ZZ['a','b']['x','z'] sage: from sage.rings.polynomial.flatten import UnflatteningMorphism sage: UnflatteningMorphism(R, S) Traceback (most recent call last): ... ValueError: rings must have same base ring :: sage: R = QQ['a','b','x','y'] sage: S = QQ['a','b']['x','z','w'] sage: from sage.rings.polynomial.flatten import UnflatteningMorphism sage: UnflatteningMorphism(R, S) Traceback (most recent call last): ... ValueError: rings must have the same number of variables """ if not is_MPolynomialRing(domain): raise ValueError("domain should be a multivariate polynomial ring") if not is_PolynomialRing(codomain) and not is_MPolynomialRing(codomain): raise ValueError("codomain should be a polynomial ring") ring = codomain intermediate_rings = [] while is_PolynomialRing(ring) or is_MPolynomialRing(ring): intermediate_rings.append(ring) ring = ring.base_ring() if domain.base_ring() != intermediate_rings[-1].base_ring(): raise ValueError("rings must have same base ring") if domain.ngens() != sum([R.ngens() for R in intermediate_rings]): raise ValueError("rings must have the same number of variables") self._intermediate_rings = intermediate_rings self._intermediate_rings.reverse() Morphism.__init__(self, domain, codomain) self._repr_type_str = 'Unflattening'
def __init__(self, map, base_ring=None, cohomology=False): """ INPUT: - ``map`` -- the map of simplicial complexes - ``base_ring`` -- a field (optional, default ``QQ``) - ``cohomology`` -- boolean (optional, default ``False``). If ``True``, return the induced map in cohomology rather than homology. EXAMPLES:: sage: from sage.homology.homology_morphism import InducedHomologyMorphism sage: K = simplicial_complexes.RandomComplex(8, 3) sage: H = Hom(K,K) sage: id = H.identity() sage: f = InducedHomologyMorphism(id, QQ) sage: f.to_matrix(0) == 1 and f.to_matrix(1) == 1 and f.to_matrix(2) == 1 True sage: f = InducedHomologyMorphism(id, ZZ) Traceback (most recent call last): ... ValueError: the coefficient ring must be a field sage: S1 = simplicial_complexes.Sphere(1).barycentric_subdivision() sage: S1.is_mutable() True sage: g = Hom(S1, S1).identity() sage: h = g.induced_homology_morphism(QQ) Traceback (most recent call last): ... ValueError: the domain and codomain complexes must be immutable sage: S1.set_immutable() sage: g = Hom(S1, S1).identity() sage: h = g.induced_homology_morphism(QQ) """ if (isinstance(map.domain(), SimplicialComplex) and (map.domain().is_mutable() or map.codomain().is_mutable())): raise ValueError('the domain and codomain complexes must be immutable') if base_ring is None: base_ring = QQ if not base_ring.is_field(): raise ValueError('the coefficient ring must be a field') self._cohomology = cohomology self._map = map self._base_ring = base_ring if cohomology: domain = map.codomain().cohomology_ring(base_ring=base_ring) codomain = map.domain().cohomology_ring(base_ring=base_ring) Morphism.__init__(self, Hom(domain, codomain, category=GradedAlgebrasWithBasis(base_ring))) else: domain = map.domain().homology_with_basis(base_ring=base_ring, cohomology=cohomology) codomain = map.codomain().homology_with_basis(base_ring=base_ring, cohomology=cohomology) Morphism.__init__(self, Hom(domain, codomain, category=GradedModulesWithBasis(base_ring)))
def __init__(self, map, base_ring=None, cohomology=False): """ INPUT: - ``map`` -- the map of simplicial complexes - ``base_ring`` -- a field (optional, default ``QQ``) - ``cohomology`` -- boolean (optional, default ``False``). If ``True``, return the induced map in cohomology rather than homology. EXAMPLES:: sage: from sage.homology.homology_morphism import InducedHomologyMorphism sage: K = simplicial_complexes.RandomComplex(8, 3) sage: H = Hom(K,K) sage: id = H.identity() sage: f = InducedHomologyMorphism(id, QQ) sage: f.to_matrix(0) == 1 and f.to_matrix(1) == 1 and f.to_matrix(2) == 1 True sage: f = InducedHomologyMorphism(id, ZZ) Traceback (most recent call last): ... ValueError: the coefficient ring must be a field sage: S1 = simplicial_complexes.Sphere(1).barycentric_subdivision() sage: S1.is_mutable() True sage: g = Hom(S1, S1).identity() sage: h = g.induced_homology_morphism(QQ) Traceback (most recent call last): ... ValueError: the domain and codomain complexes must be immutable sage: S1.set_immutable() sage: g = Hom(S1, S1).identity() sage: h = g.induced_homology_morphism(QQ) """ if (isinstance(map.domain(), SimplicialComplex) and (map.domain().is_mutable() or map.codomain().is_mutable())): raise ValueError('the domain and codomain complexes must be immutable') if base_ring is None: base_ring = QQ if not base_ring.is_field(): raise ValueError('the coefficient ring must be a field') self._cohomology = cohomology self._map = map self._base_ring = base_ring if cohomology: domain = map.domain().cohomology_ring(base_ring=base_ring) codomain = map.codomain().cohomology_ring(base_ring=base_ring) Morphism.__init__(self, Hom(domain, codomain, category=GradedAlgebrasWithBasis(base_ring))) else: domain = map.domain().homology_with_basis(base_ring=base_ring, cohomology=cohomology) codomain = map.codomain().homology_with_basis(base_ring=base_ring, cohomology=cohomology) Morphism.__init__(self, Hom(domain, codomain, category=GradedModulesWithBasis(base_ring)))
def __init__(self, parent, basis=None): """ TESTS:: sage: R.<x> = QQ[[]] sage: W, from_W, to_W = R.free_module(R, basis=(1-x)) sage: TestSuite(from_W).run(skip='_test_nonzero_equal') """ Morphism.__init__(self, parent) self._basis = basis
def __init__(self, parent, basis=None): """ TESTS:: sage: R = Zmod(8) sage: W, from_W, to_W = R.free_module(R, basis=3) sage: TestSuite(to_W).run() """ Morphism.__init__(self, parent) self._basis = basis
def __init__(self, parent): r""" TESTS:: sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone sage: isinstance(pAdicValuation(ZZ, 2), DiscretePseudoValuation) True """ Morphism.__init__(self, parent=parent)
def __init__(self, parent): r""" TESTS:: sage: from sage.rings.valuation.valuation import DiscretePseudoValuation sage: isinstance(ZZ.valuation(2), DiscretePseudoValuation) True """ Morphism.__init__(self, parent=parent)
def __init__(self, parent): """ Set-theoretic map between matrix groups. EXAMPLES:: sage: from sage.groups.matrix_gps.morphism import MatrixGroupMap sage: MatrixGroupMap(ZZ.Hom(ZZ)) # mathematical nonsense MatrixGroup endomorphism of Integer Ring """ Morphism.__init__(self, parent)
def __init__(self, parent, phi, check=True): """ A morphism between finitely generated modules over a PID. EXAMPLES:: sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],ZZ); W = V.span([2*V.0+4*V.1, 9*V.0+12*V.1, 4*V.2]) sage: Q = V/W; Q Finitely generated module V/W over Integer Ring with invariants (4, 12) sage: phi = Q.hom([Q.0+3*Q.1, -Q.1]); phi Morphism from module over Integer Ring with invariants (4, 12) to module with invariants (4, 12) that sends the generators to [(1, 3), (0, 11)] sage: phi(Q.0) == Q.0 + 3*Q.1 True sage: phi(Q.1) == -Q.1 True For full documentation, see :class:`FGP_Morphism`. """ Morphism.__init__(self, parent) M = parent.domain() N = parent.codomain() if isinstance(phi, FGP_Morphism): if check: if phi.parent() != parent: raise TypeError phi = phi._phi check = False # no need # input: phi is a morphism from MO = M.optimized().V() to N.V() # that sends MO.W() to N.W() if check: if not is_Morphism(phi) and M == N: A = M.optimized()[0].V() B = N.V() s = M.base_ring()(phi) * B.coordinate_module(A).basis_matrix() phi = A.Hom(B)(s) MO, _ = M.optimized() if phi.domain() != MO.V(): raise ValueError( "domain of phi must be the covering module for the optimized covering module of the domain" ) if phi.codomain() != N.V(): raise ValueError( "codomain of phi must be the covering module the codomain." ) # check that MO.W() gets sent into N.W() # todo (optimize): this is slow: for x in MO.W().basis(): if phi(x) not in N.W(): raise ValueError( "phi must send optimized submodule of M.W() into N.W()" ) self._phi = phi
def __init__(self, domain): r""" EXAMPLE:: sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) sage: F = QQbar.coerce_map_from(G); F Generic morphism: From: Additive abelian group isomorphic to Z + Z embedded in Algebraic Field To: Algebraic Field sage: type(F) <class 'sage.groups.additive_abelian.additive_abelian_wrapper.UnwrappingMorphism'> """ Morphism.__init__(self, domain.Hom(domain.universe()))
def __init__(self, domain): r""" EXAMPLES:: sage: G = AdditiveAbelianGroupWrapper(QQbar, [sqrt(QQbar(2)), sqrt(QQbar(3))], [0, 0]) sage: F = QQbar.coerce_map_from(G); F Generic morphism: From: Additive abelian group isomorphic to Z + Z embedded in Algebraic Field To: Algebraic Field sage: type(F) <class 'sage.groups.additive_abelian.additive_abelian_wrapper.UnwrappingMorphism'> """ Morphism.__init__(self, domain.Hom(domain.universe()))
def __init__(self, domain): r""" TESTS:: sage: from sage.modular.pollack_stevens.sigma0 import Sigma0, _Sigma0Embedding sage: x = _Sigma0Embedding(Sigma0(3)) sage: TestSuite(x).run(skip=['_test_category']) # TODO: The category test breaks because _Sigma0Embedding is not an instance of # the element class of its parent (a homset in the category of # monoids). I have no idea how to fix this. """ Morphism.__init__(self, domain.Hom(domain._matrix_space, category=Monoids()))
def __init__(self, model, A, check=True): r""" See :class:`HyperbolicIsometry` for full documentation. EXAMPLES:: sage: A = HyperbolicPlane().UHP().get_isometry(matrix(2, [0,1,-1,0])) sage: TestSuite(A).run(skip="_test_category") """ if check: model.isometry_test(A) self._matrix = copy(A) # Make a copy of the potentially mutable matrix self._matrix.set_immutable() # Make it immutable Morphism.__init__(self, Hom(model, model))
def __init__(self, S, R): """ Initialization. EXAMPLES:: sage: K.<a> = Qq(2^10) sage: R.<x> = K[] sage: W.<w> = K.extension(x^4 + 2*a*x^2 - 16*x - 6*a) sage: f = K.convert_map_from(W); type(f) <class 'sage.rings.padics.relative_extension_leaves.pAdicRelativeBaseringSection'> """ from sage.categories.sets_with_partial_maps import SetsWithPartialMaps Morphism.__init__(self, Hom(S, R, SetsWithPartialMaps()))
def __init__(self, domain, codomain) : """ INPUT: - ``domain`` -- A ring; The base ring. - ``codomain`` -- A ring; The ring of monoid power series. TESTS:: sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_functor import MonoidPowerSeriesFunctor, MonoidPowerSeriesBaseRingInjection sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid sage: mps = MonoidPowerSeriesFunctor(NNMonoid(False))(ZZ) sage: binj = MonoidPowerSeriesBaseRingInjection(ZZ, mps) """ Morphism.__init__(self, domain, codomain) self._repr_type_str = "MonoidPowerSeries base injection"
def __init__(self, UCF): r""" INPUT: - ``UCF`` -- a universal cyclotomic field TESTS:: sage: UCF = UniversalCyclotomicField() sage: UCF.coerce_embedding() Generic morphism: From: Universal Cyclotomic Field To: Algebraic Field """ Morphism.__init__(self, UCF, QQbar)
def __init__(self, domain, codomain): """ Initialize ``self``. EXAMPLES:: sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() sage: f = L.lift We skip the category test since this is currently not an element of a homspace:: sage: TestSuite(f).run(skip="_test_category") """ Morphism.__init__(self, Hom(domain, codomain))
def __init__(self, parent, phi, check=True): """ A morphism between finitely generated modules over a PID. EXAMPLES:: sage: V = span([[1/2,1,1],[3/2,2,1],[0,0,1]],ZZ); W = V.span([2*V.0+4*V.1, 9*V.0+12*V.1, 4*V.2]) sage: Q = V/W; Q Finitely generated module V/W over Integer Ring with invariants (4, 12) sage: phi = Q.hom([Q.0+3*Q.1, -Q.1]); phi Morphism from module over Integer Ring with invariants (4, 12) to module with invariants (4, 12) that sends the generators to [(1, 3), (0, 11)] sage: phi(Q.0) == Q.0 + 3*Q.1 True sage: phi(Q.1) == -Q.1 True For full documentation, see :class:`FGP_Morphism`. """ Morphism.__init__(self, parent) M = parent.domain() N = parent.codomain() if isinstance(phi, FGP_Morphism): if check: if phi.parent() != parent: raise TypeError phi = phi._phi check = False # no need # input: phi is a morphism from MO = M.optimized().V() to N.V() # that sends MO.W() to N.W() if check: if not is_Morphism(phi) and M == N: A = M.optimized()[0].V() B = N.V() s = M.base_ring()(phi) * B.coordinate_module(A).basis_matrix() phi = A.Hom(B)(s) MO, _ = M.optimized() if phi.domain() != MO.V(): raise ValueError("domain of phi must be the covering module for the optimized covering module of the domain") if phi.codomain() != N.V(): raise ValueError("codomain of phi must be the covering module the codomain.") # check that MO.W() gets sent into N.W() # todo (optimize): this is slow: for x in MO.W().basis(): if phi(x) not in N.W(): raise ValueError("phi must send optimized submodule of M.W() into N.W()") self._phi = phi
def __init__(self, domain, codomain): """ Construct the morphism TESTS:: sage: Z4 = AbelianGroupWithValues([I], [4]) sage: from sage.groups.abelian_gps.values import AbelianGroupWithValuesEmbedding sage: AbelianGroupWithValuesEmbedding(Z4, Z4.values_group()) Generic morphism: From: Multiplicative Abelian group isomorphic to C4 To: Symbolic Ring """ assert domain.values_group() is codomain from sage.categories.homset import Hom Morphism.__init__(self, Hom(domain, codomain))
def __init__(self, UCF): r""" INPUT: - ``UCF`` -- a universal cyclotomic field TESTS:: sage: UCF = UniversalCyclotomicField() sage: UCF.coerce_embedding() Generic morphism: From: Universal Cyclotomic Field To: Algebraic Field """ from sage.rings.qqbar import QQbar Morphism.__init__(self, UCF, QQbar)
def _composition_(self, other, homset): """ Return the composition of this elliptic-curve morphism with another elliptic-curve morphism. EXAMPLES:: sage: E = EllipticCurve(GF(19), [1,0]) sage: phi = E.isogeny(E(0,0)) sage: iso = E.change_weierstrass_model(5,0,0,0).isomorphism_to(E) sage: phi * iso Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 9*x over Finite Field of size 19 to Elliptic Curve defined by y^2 = x^3 + 15*x over Finite Field of size 19 sage: phi.dual() * phi Composite map: From: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 To: Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 Defn: Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 to Elliptic Curve defined by y^2 = x^3 + 15*x over Finite Field of size 19 then Isogeny of degree 2 from Elliptic Curve defined by y^2 = x^3 + 15*x over Finite Field of size 19 to Elliptic Curve defined by y^2 = x^3 + x over Finite Field of size 19 """ if not isinstance(self, EllipticCurveHom) or not isinstance( other, EllipticCurveHom): raise TypeError(f'cannot compose {type(self)} with {type(other)}') ret = self._composition_impl(self, other) if ret is not NotImplemented: return ret ret = other._composition_impl(self, other) if ret is not NotImplemented: return ret # fall back to generic formal composite map return Morphism._composition_(self, other, homset)
def __init__(self, f, X, Y): """ Input is a dictionary ``f``, the domain ``X``, and the codomain ``Y``. One can define the dictionary on the vertices of `X`. EXAMPLES:: sage: S = SimplicialComplex([[0,1],[2],[3,4],[5]], is_mutable=False) sage: H = Hom(S,S) sage: f = {0:0,1:1,2:2,3:3,4:4,5:5} sage: g = {0:0,1:1,2:0,3:3,4:4,5:0} sage: x = H(f) sage: y = H(g) sage: x == y False sage: x.image() Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(2,), (5,), (0, 1), (3, 4)} sage: y.image() Simplicial complex with vertex set (0, 1, 3, 4) and facets {(0, 1), (3, 4)} sage: x.image() == y.image() False """ if not isinstance(X, SimplicialComplex) or not isinstance( Y, SimplicialComplex): raise ValueError("X and Y must be SimplicialComplexes") if not set(f.keys()) == set(X.vertices()): raise ValueError( "f must be a dictionary from the vertex set of X to single values in the vertex set of Y" ) dim = X.dimension() Y_faces = Y.faces() for k in range(dim + 1): for i in X.faces()[k]: tup = i.tuple() fi = [] for j in tup: fi.append(f[j]) v = Simplex(set(fi)) if v not in Y_faces[v.dimension()]: raise ValueError( "f must be a dictionary from the vertices of X to the vertices of Y" ) self._vertex_dictionary = f Morphism.__init__(self, Hom(X, Y, SimplicialComplexes()))
def __init__(self, domain, codomain): r""" INPUT: - ``domain`` -- A ring; The base ring. - ``codomain`` -- A ring; The ring of monoid power series. TESTS:: sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_functor import MonoidPowerSeriesRingFunctor, MonoidPowerSeriesModuleFunctor, MonoidPowerSeriesBaseRingInjection sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid sage: mps = MonoidPowerSeriesRingFunctor(NNMonoid(False))(ZZ) sage: binj = MonoidPowerSeriesBaseRingInjection(ZZ, mps) sage: mps = MonoidPowerSeriesModuleFunctor(ZZ,NNMonoid(False))(FreeModule(ZZ, 1)) sage: binj = MonoidPowerSeriesBaseRingInjection(ZZ, mps) """ Morphism.__init__(self, domain, codomain) self._repr_type_str = "MonoidPowerSeries base injection"
def __init__(self, R, S): """ Initialization. EXAMPLES:: sage: K.<a> = Qq(125) sage: R.<x> = K[] sage: W.<w> = K.extension(x^3 + 15*a*x - 5*(1+a^2)) sage: f = W.coerce_map_from(K) sage: type(f) <class 'sage.rings.padics.relative_extension_leaves.pAdicRelativeBaseringInjection'> """ if not R.is_field() or S.is_field(): Morphism.__init__(self, Hom(R, S)) else: from sage.categories.sets_with_partial_maps import SetsWithPartialMaps Morphism.__init__(self, Hom(R, S, SetsWithPartialMaps()))
def __init__(self, parent, base): r""" TESTS:: sage: sys.path.append(os.getcwd()); from completion import * sage: v = pAdicValuation(QQ, 2) sage: K = Completion(QQ, v) sage: R.<x> = K[] sage: L = K.extension(x^2 + x + 1) sage: f = L.vector_space()[2] sage: isinstance(f, CompletionToVectorSpace) True """ Morphism.__init__(self, parent) UniqueRepresentation.__init__(self) self._base = base
def __init__(self, parent, base): r""" TESTS:: sage: from henselization import * sage: K = QQ.henselization(2) sage: R.<x> = K[] sage: L = K.extension(x^2 + x + 1) sage: f = L.module()[2] sage: from sage.rings.padics.henselization.maps import HenselizationToVectorSpace sage: isinstance(f, HenselizationToVectorSpace) True """ Morphism.__init__(self, parent) UniqueRepresentation.__init__(self) self._base = base
def __init__(self, domain, D): """ Initialize the morphism with a domain and dictionary of specializations EXAMPLES:: sage: R.<a,c> = QQ[] sage: S.<x,y> = R[] sage: from sage.rings.polynomial.flatten import FractionSpecializationMorphism sage: phi = FractionSpecializationMorphism(Frac(S), {c:3}) sage: phi Fraction Specialization morphism: From: Fraction Field of Multivariate Polynomial Ring in x, y over Multivariate Polynomial Ring in a, c over Rational Field To: Fraction Field of Multivariate Polynomial Ring in x, y over Univariate Polynomial Ring in a over Rational Field """ if not is_FractionField(domain): raise TypeError("domain must be a fraction field") self._specialization = SpecializationMorphism(domain.base(), D) self._repr_type_str = 'Fraction Specialization' Morphism.__init__(self, domain, self._specialization.codomain().fraction_field())
def __init__(self, domain, codomain): r""" Initialize this morphism. EXAMPLES:: sage: R.<t> = QQ[] sage: sigma = R.hom([t+1]) sage: S.<x> = R['x',sigma] sage: K = S.fraction_field() sage: K.coerce_map_from(K.base_ring()) # indirect doctest Ore Function base injection morphism: From: Fraction Field of Univariate Polynomial Ring in t over Rational Field To: Ore Function Field in x over Fraction Field of Univariate Polynomial Ring in t over Rational Field twisted by t |--> t + 1 """ assert codomain.base_ring() is domain, \ "the domain of the injection must be the base ring of the Ore function field" Morphism.__init__(self, Hom(domain, codomain)) self._an_element = codomain.gen() self._repr_type_str = "Ore Function base injection"
def __init__(self, G, H, genss, imgss): from sage.categories.homset import Hom Morphism.__init__(self, Hom(G, H)) if len(genss) != len(imgss): raise TypeError("Sorry, the lengths of %s, %s must be equal." % (genss, imgss)) self._domain = G self._codomain = H if not(G.is_abelian()): raise TypeError("Sorry, the groups must be abelian groups.") if not(H.is_abelian()): raise TypeError("Sorry, the groups must be abelian groups.") G_domain = G.subgroup(genss) if G_domain.order() != G.order(): raise TypeError("Sorry, the list %s must generate G." % genss) # self.domain_invs = G.gens_orders() # self.codomaininvs = H.gens_orders() self.domaingens = genss self.codomaingens = imgss for i in range(len(self.domaingens)): if (self.domaingens[i]).order() != (self.codomaingens[i]).order(): raise TypeError("Sorry, the orders of the corresponding elements in %s, %s must be equal." % (genss, imgss))
def __init__(self, E, kernel): if not is_EdwardsCurve(E): raise TypeError("E parameter must be an EdwardsCurve.") if not isinstance(kernel, type([1,1])) and kernel in E : # a single point was given, we put it in a list # the first condition assures that [1,1] is treated as x+1 kernel = [E(kernel)] if isinstance(kernel, list): for P in kernel: if P not in E: raise ValueError("The generators of the kernel of the isogeny must first lie on the EdwardsCurve") self.__E1 = E #domain curve self.__E2 = None #codomain curve; not yet found self.__degree = None self.__base_field = E.base_ring() self.__kernel_gens = kernel self.__kernel_list = None self.__degree = None self.__poly_ring = PolynomialRing(self.__base_field, ['x','y']) self.__x_var = self.__poly_ring('x') self.__y_var = self.__poly_ring('y') # to determine the codomain, and the x and y rational maps self.__initialize_kernel_list() self.__compute_B() self.__compute_E2() self.__initialize_rational_maps() self._domain = self.__E1 self._codomain = self.__E2 # sets up the parent parent = homset.Hom(self.__E1(0).parent(), self.__E2(0).parent()) Morphism.__init__(self, parent)
def __init__(self,f,X,Y): """ Input is a dictionary ``f``, the domain ``X``, and the codomain ``Y``. One can define the dictionary on the vertices of `X`. EXAMPLES:: sage: S = SimplicialComplex([[0,1],[2],[3,4],[5]], is_mutable=False) sage: H = Hom(S,S) sage: f = {0:0,1:1,2:2,3:3,4:4,5:5} sage: g = {0:0,1:1,2:0,3:3,4:4,5:0} sage: x = H(f) sage: y = H(g) sage: x == y False sage: x.image() Simplicial complex with vertex set (0, 1, 2, 3, 4, 5) and facets {(3, 4), (5,), (2,), (0, 1)} sage: y.image() Simplicial complex with vertex set (0, 1, 3, 4) and facets {(3, 4), (0, 1)} sage: x.image() == y.image() False """ if not isinstance(X,SimplicialComplex) or not isinstance(Y,SimplicialComplex): raise ValueError("X and Y must be SimplicialComplexes") if not set(f.keys()) == set(X._vertex_set): raise ValueError("f must be a dictionary from the vertex set of X to single values in the vertex set of Y") dim = X.dimension() Y_faces = Y.faces() for k in range(dim+1): for i in X.faces()[k]: tup = i.tuple() fi = [] for j in tup: fi.append(f[j]) v = Simplex(set(fi)) if not v in Y_faces[v.dimension()]: raise ValueError("f must be a dictionary from the vertices of X to the vertices of Y") self._vertex_dictionary = f Morphism.__init__(self, Hom(X,Y,SimplicialComplexes()))
def _repr_(self): r""" Return string representation of this morphism. EXAMPLES:: sage: t = J0(11).hecke_operator(2) sage: sage.modular.abvar.morphism.Morphism_abstract._repr_(t) 'Abelian variety endomorphism of Abelian variety J0(11) of dimension 1' sage: J0(42).projection(J0(42)[0])._repr_() 'Abelian variety morphism:\n From: Abelian variety J0(42) of dimension 5\n To: Simple abelian subvariety 14a(1,42) of dimension 1 of J0(42)' """ return base_Morphism._repr_(self)
def __init__(self, domain, codomain): r""" INPUT: - ``domain`` -- A ring. - ``codomain`` -- A ring of graded expansions. TESTS:: sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import * sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import * sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import * sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import * sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_functor import * sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False)) sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1: 1}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1: 1, 2: 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2))) sage: GradedExpansionBaseringInjection(QQ, ger) Base ring injection of Graded expansion ring with generators a, b morphism: From: Rational Field To: Graded expansion ring with generators a, b """ Morphism.__init__(self, domain, codomain) self._repr_type_str = "Base ring injection of %s" % (codomain, )
def __init__(self, domain, codomain ) : r""" INPUT: - ``domain`` -- A ring. - ``codomain`` -- A ring of graded expansions. TESTS:: sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import * sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import * sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import * sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import * sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_functor import * sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False)) sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1: 1}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1: 1, 2: 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2))) sage: GradedExpansionBaseringInjection(QQ, ger) Base ring injection of Graded expansion ring with generators a, b morphism: From: Rational Field To: Graded expansion ring with generators a, b """ Morphism.__init__(self, domain, codomain) self._repr_type_str = "Base ring injection of %s" % (codomain,)
def __repr__(self): r""" Return the string representation of this WeierstrassIsomorphism. OUTPUT: (string) The underlying morphism, together with an extra line showing the `(u,r,s,t)` parameters. EXAMPLES:: sage: E1 = EllipticCurve('5077') sage: E2 = E1.change_weierstrass_model([2,3,4,5]) sage: E1.isomorphism_to(E2) Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 + y = x^3 - 7*x + 6 over Rational Field To: Abelian group of points on Elliptic Curve defined by y^2 + 4*x*y + 11/8*y = x^3 - 7/4*x^2 - 3/2*x - 9/32 over Rational Field Via: (u,r,s,t) = (2, 3, 4, 5) """ return Morphism.__repr__(self) + "\n Via: (u,r,s,t) = " + baseWI.__repr__(self)
def __init__(self, matrices, f, g=None): r""" Create a chain homotopy between the given chain maps from a dictionary of matrices. EXAMPLES: If ``g`` is not specified, it is set equal to `f - (H \partial + \partial H)`. :: sage: from sage.homology.chain_homotopy import ChainHomotopy sage: C = ChainComplex({1: matrix(ZZ, 1, 2, (1,0)), 2: matrix(ZZ, 2, 1, (0, 2))}, degree_of_differential=-1) sage: D = ChainComplex({2: matrix(ZZ, 1, 1, (6,))}, degree_of_differential=-1) sage: f_d = {1: matrix(ZZ, 1, 2, (0,3)), 2: identity_matrix(ZZ, 1)} sage: f = Hom(C,D)(f_d) sage: H_d = {0: identity_matrix(ZZ, 1), 1: matrix(ZZ, 1, 2, (2,2))} sage: H = ChainHomotopy(H_d, f) sage: H._g.in_degree(0) [] sage: H._g.in_degree(1) [-13 -9] sage: H._g.in_degree(2) [-3] TESTS: Try to construct a chain homotopy in which the maps do not have matching domains and codomains:: sage: g = Hom(C,C)({}) # the zero chain map sage: H = ChainHomotopy(H_d, f, g) Traceback (most recent call last): ... ValueError: the chain maps are not compatible """ domain = f.domain() codomain = f.codomain() deg = domain.degree_of_differential() # Check that the chain complexes are compatible. This should # never arise, because first there should be errors in # constructing the chain maps. But just in case... if domain.degree_of_differential() != codomain.degree_of_differential(): raise ValueError('the chain complexes are not compatible') if g is not None: # Check that the chain maps are compatible. if not (domain == g.domain() and codomain == g.codomain()): raise ValueError('the chain maps are not compatible') # Check that the data define a chain homotopy. for i in domain.differential(): if i in matrices and i+deg in matrices: if not (codomain.differential(i-deg) * matrices[i] + matrices[i+deg] * domain.differential(i) == f.in_degree(i) - g.in_degree(i)): raise ValueError('the data do not define a valid chain homotopy') elif i in matrices: if not (codomain.differential(i-deg) * matrices[i] == f.in_degree(i) - g.in_degree(i)): raise ValueError('the data do not define a valid chain homotopy') elif i+deg in matrices: if not (matrices[i+deg] * domain.differential(i) == f.in_degree(i) - g.in_degree(i)): raise ValueError('the data do not define a valid chain homotopy') else: # Define g. g_data = {} for i in domain.differential(): if i in matrices and i+deg in matrices: g_data[i] = f.in_degree(i) - matrices[i+deg] * domain.differential(i) - codomain.differential(i-deg) * matrices[i] elif i in matrices: g_data[i] = f.in_degree(i) - codomain.differential(i-deg) * matrices[i] elif i+deg in matrices: g_data[i] = f.in_degree(i) - matrices[i+deg] * domain.differential(i) g = ChainComplexMorphism(g_data, domain, codomain) self._matrix_dictionary = {} for i in matrices: m = matrices[i] # Use immutable matrices because they're hashable. m.set_immutable() self._matrix_dictionary[i] = m self._f = f self._g = g Morphism.__init__(self, Hom(domain, codomain))
def __init__(self, domain, D): """ The Python constructor EXAMPLES:: sage: S.<x,y> = PolynomialRing(QQ) sage: D = dict({x:1}) sage: from sage.rings.polynomial.flatten import SpecializationMorphism sage: phi = SpecializationMorphism(S, D); phi Specialization morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in y over Rational Field sage: phi(x^2 + y^2) y^2 + 1 :: sage: R.<a,b,c> = PolynomialRing(ZZ) sage: S.<x,y,z> = PolynomialRing(R) sage: from sage.rings.polynomial.flatten import SpecializationMorphism sage: xi = SpecializationMorphism(S, {a:1/2}) Traceback (most recent call last): ... ValueError: values must be in base ring """ if not is_PolynomialRing(domain) and not is_MPolynomialRing(domain): raise ValueError("domain should be a polynomial ring") phi = FlatteningMorphism(domain) newD = dict() for k in D.keys(): newD[phi(k)] = D[k] self._im_dict = newD self._flattening_morph = phi base = phi.codomain().base_ring() if not all([c in base for c in D.values()]): raise ValueError("values must be in base ring") #make unflattened codomain old_vars = [] ring = domain while is_PolynomialRing(ring) or is_MPolynomialRing(ring): old_vars.append([ring.gens(), is_MPolynomialRing(ring)]) ring = ring.base_ring() new_vars = [[[t for t in v if t not in newD.keys()], b] for v,b in old_vars] new_vars.reverse() old_vars.reverse() R = ring.base_ring() new_gens=[] for i in range(len(new_vars)): if new_vars[i][0] != []: #check to see if it should be multi or univariate if not new_vars[i][1] or (len(new_vars[i][0])==1 and len(old_vars[i][0])>1): R = PolynomialRing(R, new_vars[i][0]) else: R = PolynomialRing(R, new_vars[i][0], len(new_vars[i][0])) new_gens.extend(list(R.gens())) old_gens = [t for v in new_vars for t in v] #unflattening eval vals = [] ind = 0 for t in phi.codomain().gens(): if t in newD.keys(): vals.append(newD[t]) else: vals.append(new_gens[ind]) ind += 1 psi = phi.codomain().hom(vals, R) self._unflattening_morph = psi self._repr_type_str = 'Specialization' Morphism.__init__(self, domain, R)
def __init__(self, parent, matrix_rep, bases=None, name=None, latex_name=None, is_identity=False): r""" TESTS: Generic homomorphism:: sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: N = FiniteRankFreeModule(ZZ, 2, name='N') sage: e = M.basis('e') ; f = N.basis('f') sage: from sage.tensor.modules.free_module_morphism import FiniteRankFreeModuleMorphism sage: phi = FiniteRankFreeModuleMorphism(Hom(M,N), [[1,0,-3], [2,1,4]], ....: name='phi', latex_name=r'\phi') sage: phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring sage: phi.matrix(e,f) [ 1 0 -3] [ 2 1 4] sage: latex(phi) \phi Generic endomorphism:: sage: phi = FiniteRankFreeModuleMorphism(End(M), [[1,0,-3], [2,1,4], [7,8,9]], ....: name='phi', latex_name=r'\phi') sage: phi Generic endomorphism of Rank-3 free module M over the Integer Ring Identity endomorphism:: sage: phi = FiniteRankFreeModuleMorphism(End(M), 'whatever', is_identity=True) sage: phi Identity endomorphism of Rank-3 free module M over the Integer Ring sage: phi.matrix(e) [1 0 0] [0 1 0] [0 0 1] sage: latex(phi) \mathrm{Id} """ from sage.matrix.constructor import matrix from sage.misc.constant_function import ConstantFunction Morphism.__init__(self, parent) fmodule1 = parent.domain() fmodule2 = parent.codomain() if bases is None: def_basis1 = fmodule1.default_basis() if def_basis1 is None: raise ValueError("the {} has no default ".format(fmodule1) + "basis") def_basis2 = fmodule2.default_basis() if def_basis2 is None: raise ValueError("the {} has no default ".format(fmodule2) + "basis") bases = (def_basis1, def_basis2) else: bases = tuple(bases) # insures bases is a tuple if len(bases) != 2: raise TypeError("the argument bases must contain 2 bases") if bases[0] not in fmodule1.bases(): raise TypeError("{} is not a basis on the {}".format(bases[0], fmodule1)) if bases[1] not in fmodule2.bases(): raise TypeError("{} is not a basis on the {}".format(bases[1], fmodule2)) ring = parent.base_ring() n1 = fmodule1.rank() n2 = fmodule2.rank() if is_identity: # Construction of the identity endomorphism if fmodule1 != fmodule2: raise TypeError("the domain and codomain must coincide " + \ "for the identity endomorphism.") if bases[0] != bases[1]: raise TypeError("the two bases must coincide for " + \ "constructing the identity endomorphism.") self._is_identity = True zero = ring.zero() one = ring.one() matrix_rep = [] for i in range(n1): row = [zero]*n1 row[i] = one matrix_rep.append(row) if name is None: name = 'Id' if latex_name is None and name == 'Id': latex_name = r'\mathrm{Id}' self._repr_type_str = 'Identity' else: # Construction of a generic morphism self._is_identity = False if isinstance(matrix_rep, ConstantFunction): # the zero morphism if matrix_rep().is_zero(): matrix_rep = 0 if matrix_rep == 1: if fmodule1 == fmodule2: # the identity endomorphism (again): self._is_identity = True self._repr_type_str = 'Identity' name = 'Id' latex_name = r'\mathrm{Id}' self._matrices = {bases: matrix(ring, n2, n1, matrix_rep)} self._name = name if latex_name is None: self._latex_name = self._name else: self._latex_name = latex_name
def __init__(self, domain): """ The Python constructor EXAMPLES:: sage: R = ZZ['a', 'b', 'c']['x', 'y', 'z'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: FlatteningMorphism(R) Flattening morphism: From: Multivariate Polynomial Ring in x, y, z over Multivariate Polynomial Ring in a, b, c over Integer Ring To: Multivariate Polynomial Ring in a, b, c, x, y, z over Integer Ring :: sage: R = ZZ['a']['b']['c'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: FlatteningMorphism(R) Flattening morphism: From: Univariate Polynomial Ring in c over Univariate Polynomial Ring in b over Univariate Polynomial Ring in a over Integer Ring To: Multivariate Polynomial Ring in a, b, c over Integer Ring :: sage: R = ZZ['a']['a','b'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: FlatteningMorphism(R) Traceback (most recent call last): ... ValueError: clash in variable names :: sage: K.<v> = NumberField(x^3 - 2) sage: R = K['x','y']['a','b'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f(R('v*a*x^2 + b^2 + 1/v*y')) (v)*x^2*a + b^2 + (1/2*v^2)*y :: sage: R = QQbar['x','y']['a','b'] sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f(R('QQbar(sqrt(2))*a*x^2 + b^2 + QQbar(I)*y')) 1.414213562373095?*x^2*a + b^2 + I*y :: sage: R.<z> = PolynomialRing(QQbar,1) sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f.domain(), f.codomain() (Multivariate Polynomial Ring in z over Algebraic Field, Multivariate Polynomial Ring in z over Algebraic Field) :: sage: R.<z> = PolynomialRing(QQbar) sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f.domain(), f.codomain() (Univariate Polynomial Ring in z over Algebraic Field, Univariate Polynomial Ring in z over Algebraic Field) """ if not is_PolynomialRing(domain) and not is_MPolynomialRing(domain): raise ValueError("domain should be a polynomial ring") ring = domain variables = [] intermediate_rings = [] while is_PolynomialRing(ring) or is_MPolynomialRing(ring): intermediate_rings.append(ring) v = ring.variable_names() if any(vv in variables for vv in v): raise ValueError("clash in variable names") variables.extend(reversed(v)) ring = ring.base_ring() self._intermediate_rings = intermediate_rings variables.reverse() if is_MPolynomialRing(domain): codomain = PolynomialRing(ring, variables, len(variables)) else: codomain = PolynomialRing(ring, variables) Morphism.__init__(self, domain, codomain) self._repr_type_str = 'Flattening'
def __init__(self, domain, D): """ The Python constructor EXAMPLES:: sage: S.<x,y> = PolynomialRing(QQ) sage: D = dict({x:1}) sage: from sage.rings.polynomial.flatten import SpecializationMorphism sage: phi = SpecializationMorphism(S, D); phi Specialization morphism: From: Multivariate Polynomial Ring in x, y over Rational Field To: Univariate Polynomial Ring in y over Rational Field sage: phi(x^2 + y^2) y^2 + 1 :: sage: R.<a,b,c> = PolynomialRing(ZZ) sage: S.<x,y,z> = PolynomialRing(R) sage: from sage.rings.polynomial.flatten import SpecializationMorphism sage: xi = SpecializationMorphism(S, {a:1/2}) Traceback (most recent call last): ... TypeError: no conversion of this rational to integer The following was fixed in :trac:`23811`:: sage: R.<c>=RR[] sage: P.<z>=AffineSpace(R,1) sage: H=End(P) sage: f=H([z^2+c]) sage: f.specialization({c:1}) Scheme endomorphism of Affine Space of dimension 1 over Real Field with 53 bits of precision Defn: Defined on coordinates by sending (z) to (z^2 + 1.00000000000000) """ if not is_PolynomialRing(domain) and not is_MPolynomialRing(domain): raise TypeError("domain should be a polynomial ring") # We use this composition where "flat" is a flattened # polynomial ring. # # phi D psi # domain → flat → flat → R # │ │ │ # └─────────┴───────────────┘ # _flattening_morph _eval_morph # = phi = psi ∘ D phi = FlatteningMorphism(domain) flat = phi.codomain() base = flat.base_ring() # Change domain of D to "flat" and ensure that the values lie # in the base ring. D = {phi(k): base(D[k]) for k in D} # Construct unflattened codomain R new_vars = [] R = domain while is_PolynomialRing(R) or is_MPolynomialRing(R): old = R.gens() new = [t for t in old if t not in D] force_multivariate = ((len(old) == 1) and is_MPolynomialRing(R)) new_vars.append((new, force_multivariate)) R = R.base_ring() # Construct unflattening map psi (only defined on the variables # of "flat" which are not involved in D) psi = dict() for new, force_multivariate in reversed(new_vars): if not new: continue # Pass in the names of the variables var_names = [str(var) for var in new] if force_multivariate: R = PolynomialRing(R, var_names, len(var_names)) else: R = PolynomialRing(R, var_names) # Map variables in "new" to R psi.update(zip([phi(w) for w in new], R.gens())) # Compose D with psi vals = [] for t in flat.gens(): if t in D: vals.append(R.coerce(D[t])) else: vals.append(psi[t]) self._flattening_morph = phi self._eval_morph = flat.hom(vals, R) self._repr_type_str = 'Specialization' Morphism.__init__(self, domain, R)
def __init__(self, E=None, urst=None, F=None): r""" Constructor for WeierstrassIsomorphism class, INPUT: - ``E`` -- an EllipticCurve, or None (see below). - ``urst`` -- a 4-tuple `(u,r,s,t)`, or None (see below). - ``F`` -- an EllipticCurve, or None (see below). Given two Elliptic Curves ``E`` and ``F`` (represented by Weierstrass models as usual), and a transformation ``urst`` from ``E`` to ``F``, construct an isomorphism from ``E`` to ``F``. An exception is raised if ``urst(E)!=F``. At most one of ``E``, ``F``, ``urst`` can be None. If ``F==None`` then ``F`` is constructed as ``urst(E)``. If ``E==None`` then ``E`` is constructed as ``urst^-1(F)``. If ``urst==None`` then an isomorphism from ``E`` to ``F`` is constructed if possible, and an exception is raised if they are not isomorphic. Otherwise ``urst`` can be a tuple of length 4 or a object of type ``baseWI``. Users will not usually need to use this class directly, but instead use methods such as ``isomorphism`` of elliptic curves. EXAMPLES:: sage: from sage.schemes.elliptic_curves.weierstrass_morphism import * sage: WeierstrassIsomorphism(EllipticCurve([0,1,2,3,4]),(-1,2,3,4)) Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field To: Abelian group of points on Elliptic Curve defined by y^2 - 6*x*y - 10*y = x^3 - 2*x^2 - 11*x - 2 over Rational Field Via: (u,r,s,t) = (-1, 2, 3, 4) sage: E = EllipticCurve([0,1,2,3,4]) sage: F = EllipticCurve(E.cremona_label()) sage: WeierstrassIsomorphism(E,None,F) Generic morphism: From: Abelian group of points on Elliptic Curve defined by y^2 + 2*y = x^3 + x^2 + 3*x + 4 over Rational Field To: Abelian group of points on Elliptic Curve defined by y^2 = x^3 + x^2 + 3*x + 5 over Rational Field Via: (u,r,s,t) = (1, 0, 0, -1) sage: w = WeierstrassIsomorphism(None,(1,0,0,-1),F) sage: w._domain_curve==E True """ from .ell_generic import is_EllipticCurve if E is not None: if not is_EllipticCurve(E): raise ValueError("First argument must be an elliptic curve or None") if F is not None: if not is_EllipticCurve(F): raise ValueError("Third argument must be an elliptic curve or None") if urst is not None: if len(urst) != 4: raise ValueError("Second argument must be [u,r,s,t] or None") if len([par for par in [E, urst, F] if par is not None]) < 2: raise ValueError("At most 1 argument can be None") if F is None: # easy case baseWI.__init__(self, *urst) F = EllipticCurve(baseWI.__call__(self, list(E.a_invariants()))) Morphism.__init__(self, Hom(E(0).parent(), F(0).parent())) self._domain_curve = E self._codomain_curve = F return if E is None: # easy case in reverse baseWI.__init__(self, *urst) inv_urst = baseWI.__invert__(self) E = EllipticCurve(baseWI.__call__(inv_urst, list(F.a_invariants()))) Morphism.__init__(self, Hom(E(0).parent(), F(0).parent())) self._domain_curve = E self._codomain_curve = F return if urst is None: # try to construct the morphism urst = isomorphisms(E, F, True) if urst is None: raise ValueError("Elliptic curves not isomorphic.") baseWI.__init__(self, *urst) Morphism.__init__(self, Hom(E(0).parent(), F(0).parent())) self._domain_curve = E self._codomain_curve = F return # none of the parameters is None: baseWI.__init__(self, *urst) if F != EllipticCurve(baseWI.__call__(self, list(E.a_invariants()))): raise ValueError("second argument is not an isomorphism from first argument to third argument") else: Morphism.__init__(self, Hom(E(0).parent(), F(0).parent())) self._domain_curve = E self._codomain_curve = F return
def __init__(self, matrices, C, D, check=True): """ Create a morphism from a dictionary of matrices. EXAMPLES:: sage: S = simplicial_complexes.Sphere(1) sage: S Minimal triangulation of the 1-sphere sage: C = S.chain_complex() sage: C.differential() {0: [], 1: [-1 -1 0] [ 1 0 -1] [ 0 1 1], 2: []} sage: f = {0:zero_matrix(ZZ,3,3),1:zero_matrix(ZZ,3,3)} sage: G = Hom(C,C) sage: x = G(f) sage: x Chain complex endomorphism of Chain complex with at most 2 nonzero terms over Integer Ring sage: x._matrix_dictionary {0: [0 0 0] [0 0 0] [0 0 0], 1: [0 0 0] [0 0 0] [0 0 0]} Check that the bug in :trac:`13220` has been fixed:: sage: X = simplicial_complexes.Simplex(1) sage: Y = simplicial_complexes.Simplex(0) sage: g = Hom(X,Y)({0:0, 1:0}) sage: g.associated_chain_complex_morphism() Chain complex morphism: From: Chain complex with at most 2 nonzero terms over Integer Ring To: Chain complex with at most 1 nonzero terms over Integer Ring Check that an error is raised if the matrices are the wrong size:: sage: C = ChainComplex({0: zero_matrix(ZZ, 0, 1)}) sage: D = ChainComplex({0: zero_matrix(ZZ, 0, 2)}) sage: Hom(C,D)({0: matrix(1, 2, [1, 1])}) # 1x2 is the wrong size. Traceback (most recent call last): ... ValueError: matrix in degree 0 is not the right size sage: Hom(C,D)({0: matrix(2, 1, [1, 1])}) # 2x1 is right. Chain complex morphism: From: Chain complex with at most 1 nonzero terms over Integer Ring To: Chain complex with at most 1 nonzero terms over Integer Ring """ if not C.base_ring() == D.base_ring(): raise NotImplementedError('morphisms between chain complexes of different' ' base rings are not implemented') d = C.degree_of_differential() if d != D.degree_of_differential(): raise ValueError('degree of differential does not match') from sage.misc.misc import uniq degrees = uniq(list(C.differential()) + list(D.differential())) initial_matrices = dict(matrices) matrices = dict() for i in degrees: if i - d not in degrees: if not (C.free_module_rank(i) == D.free_module_rank(i) == 0): raise ValueError('{} and {} are not rank 0 in degree {}'.format(C, D, i)) continue try: matrices[i] = initial_matrices.pop(i) except KeyError: matrices[i] = zero_matrix(C.base_ring(), D.differential(i).ncols(), C.differential(i).ncols(), sparse=True) if check: # All remaining matrices given must be 0x0. if not all(m.ncols() == m.nrows() == 0 for m in initial_matrices.values()): raise ValueError('the remaining matrices are not empty') # Check sizes of matrices. for i in matrices: if (matrices[i].nrows() != D.free_module_rank(i) or matrices[i].ncols() != C.free_module_rank(i)): raise ValueError('matrix in degree {} is not the right size'.format(i)) # Check commutativity. for i in degrees: if i - d not in degrees: if not (C.free_module_rank(i) == D.free_module_rank(i) == 0): raise ValueError('{} and {} are not rank 0 in degree {}'.format(C, D, i)) continue if i + d not in degrees: if not (C.free_module_rank(i+d) == D.free_module_rank(i+d) == 0): raise ValueError('{} and {} are not rank 0 in degree {}'.format(C, D, i+d)) continue Dm = D.differential(i) * matrices[i] mC = matrices[i+d] * C.differential(i) if mC != Dm: raise ValueError('matrices must define a chain complex morphism') self._matrix_dictionary = {} for i in matrices: m = matrices[i] # Use immutable matrices because they're hashable. m.set_immutable() self._matrix_dictionary[i] = m Morphism.__init__(self, Hom(C,D, ChainComplexes(C.base_ring())))