def inverse_image(self, A): """ Given a submodule A of the codomain of this morphism, return the inverse image of A under this morphism. 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]); Q = V/W; Q Finitely generated module V/W over Integer Ring with invariants (4, 12) sage: phi = Q.hom([0, Q.1]) sage: phi.inverse_image(Q.submodule([])) Finitely generated module V/W over Integer Ring with invariants (4) sage: phi.kernel() Finitely generated module V/W over Integer Ring with invariants (4) sage: phi.inverse_image(phi.codomain()) Finitely generated module V/W over Integer Ring with invariants (4, 12) sage: phi.inverse_image(Q.submodule([Q.0])) Finitely generated module V/W over Integer Ring with invariants (4) sage: phi.inverse_image(Q.submodule([Q.1])) Finitely generated module V/W over Integer Ring with invariants (4, 12) sage: phi.inverse_image(ZZ^3) Traceback (most recent call last): ... TypeError: A must be a finitely generated quotient module sage: phi.inverse_image(ZZ^3 / W.scale(2)) Traceback (most recent call last): ... ValueError: A must be a submodule of the codomain """ from fgp_module import is_FGP_Module if not is_FGP_Module(A): raise TypeError("A must be a finitely generated quotient module") if not A.is_submodule(self.codomain()): raise ValueError("A must be a submodule of the codomain") V = self._phi.inverse_image(A.V()) D = self.domain() V = D.W() + V return D._module_constructor(V, D.W(), check=fgp_module.DEBUG)
def __call__(self, x): """ 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 sage: phi = Q.hom([Q.0+3*Q.1, -Q.1]); sage: phi(Q.0) == Q.0 + 3*Q.1 True We compute the image of some submodules of the domain:: sage: phi(Q) Finitely generated module V/W over Integer Ring with invariants (4, 12) sage: phi(Q.submodule([Q.0])) Finitely generated module V/W over Integer Ring with invariants (4) sage: phi(Q.submodule([Q.1])) Finitely generated module V/W over Integer Ring with invariants (12) sage: phi(W/W) Finitely generated module V/W over Integer Ring with invariants () We try to evaluate on a module that is not a submodule of the domain, which raises a ValueError:: sage: phi(V/W.scale(2)) Traceback (most recent call last): ... ValueError: x must be a submodule or element of the domain We evaluate on an element of the domain that is not in the V for the optimized representation of the domain:: sage: V = span([[1/2,0,0],[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: O, X = Q.optimized() sage: O.V() Free module of degree 3 and rank 2 over Integer Ring User basis matrix: [0 0 1] [0 2 0] sage: phi = Q.hom([Q.0, 4*Q.1]) sage: x = Q(V.0); x (0, 4) sage: x == 4*Q.1 True sage: x in O.V() False sage: phi(x) (0, 4) sage: phi(4*Q.1) (0, 4) sage: phi(4*Q.1) == phi(x) True """ from fgp_module import is_FGP_Module if is_FGP_Module(x): if not x.is_submodule(self.domain()): raise ValueError( "x must be a submodule or element of the domain") # perhaps can be optimized with a matrix multiply; but note # the subtlety of optimized representations. return self.codomain().submodule( [self(y) for y in x.smith_form_gens()]) else: C = self.codomain() D = self.domain() O, X = D.optimized() x = D(x) if O is D: x = x.lift() else: # Now we have to transform x so that it is in the optimized representation. x = D.V().coordinate_vector(x.lift()) * X return C(self._phi(x))
def __call__(self, x): """ 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 sage: phi = Q.hom([Q.0+3*Q.1, -Q.1]); sage: phi(Q.0) == Q.0 + 3*Q.1 True We compute the image of some submodules of the domain:: sage: phi(Q) Finitely generated module V/W over Integer Ring with invariants (4, 12) sage: phi(Q.submodule([Q.0])) Finitely generated module V/W over Integer Ring with invariants (4) sage: phi(Q.submodule([Q.1])) Finitely generated module V/W over Integer Ring with invariants (12) sage: phi(W/W) Finitely generated module V/W over Integer Ring with invariants () We try to evaluate on a module that is not a submodule of the domain, which raises a ValueError:: sage: phi(V/W.scale(2)) Traceback (most recent call last): ... ValueError: x must be a submodule or element of the domain We evaluate on an element of the domain that is not in the V for the optimized representation of the domain:: sage: V = span([[1/2,0,0],[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: O, X = Q.optimized() sage: O.V() Free module of degree 3 and rank 2 over Integer Ring User basis matrix: [0 0 1] [0 2 0] sage: phi = Q.hom([Q.0, 4*Q.1]) sage: x = Q(V.0); x (0, 4) sage: x == 4*Q.1 True sage: x in O.V() False sage: phi(x) (0, 4) sage: phi(4*Q.1) (0, 4) sage: phi(4*Q.1) == phi(x) True """ from fgp_module import is_FGP_Module if is_FGP_Module(x): if not x.is_submodule(self.domain()): raise ValueError("x must be a submodule or element of the domain") # perhaps can be optimized with a matrix multiply; but note # the subtlety of optimized representations. return self.codomain().submodule([self(y) for y in x.smith_form_gens()]) else: C = self.codomain() D = self.domain() O, X = D.optimized() x = D(x) if O is D: x = x.lift() else: # Now we have to transform x so that it is in the optimized representation. x = D.V().coordinate_vector(x.lift()) * X return C(self._phi(x))