def pushforward(self, x): """ Compute the image of a sub-module of the domain. EXAMPLES:: sage: V = QQ^3; W = span([[1,2,3],[-1,2,5/3]], QQ) sage: phi = V.hom(matrix(QQ,3,[1..9])) sage: phi.rank() 2 sage: phi(V) #indirect doctest Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [ 1 0 -1] [ 0 1 2] We compute the image of a submodule of a ZZ-module embedded in a rational vector space:: sage: V = QQ^3; W = V.span_of_basis([[2,2,3],[-1,2,5/3]], ZZ) sage: phi = W.hom([W.0, W.0-W.1]); phi Free module morphism defined by the matrix [ 1 0] [ 1 -1]... sage: phi(span([2*W.1],ZZ)) Free module of degree 3 and rank 1 over Integer Ring Echelon basis matrix: [ 6 0 8/3] sage: phi(2*W.1) (6, 0, 8/3) """ if free_module.is_FreeModule(x): V = self.domain().submodule(x) return self.restrict_domain(V).image() raise TypeError("`pushforward` is only defined for submodules")
def __init__(self, abvar, lattice, field_of_definition=QQbar, check=True): """ A finite subgroup of a modular abelian variety that is defined by a given lattice. INPUT: - ``abvar`` - a modular abelian variety - ``lattice`` - a lattice that contains the lattice of abvar - ``field_of_definition`` - the field of definition of this finite group scheme - ``check`` - bool (default: True) whether or not to check that lattice contains the abvar lattice. EXAMPLES:: sage: J = J0(11) sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1 """ if check: if not is_FreeModule(lattice) or lattice.base_ring() != ZZ: raise TypeError, "lattice must be a free module over ZZ" if not abelian_variety.is_ModularAbelianVariety(abvar): raise TypeError, "abvar must be a modular abelian variety" if not abvar.lattice().is_submodule(lattice): lattice += abvar.lattice() if lattice.rank() != abvar.lattice().rank(): raise ValueError, "lattice must contain the lattice of abvar with finite index" FiniteSubgroup.__init__(self, abvar, field_of_definition) self.__lattice = lattice
def __init__(self, X, Y, category=None): """ 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 sage: type(Q.Hom(Q)) <class 'sage.modules.fg_pid.fgp_morphism.FGP_Homset_class_with_category'> """ if category is None: from sage.modules.free_module import is_FreeModule if is_FreeModule(X) and is_FreeModule(Y): from sage.all import FreeModules category = FreeModules(X.base_ring()) else: from sage.all import Modules category = Modules(X.base_ring()) Homset.__init__(self, X, Y, category)
def __call__(self, x): """ Evaluate this matrix morphism at x, which is either an element that can be coerced into the domain or a submodule of the domain. EXAMPLES:: sage: V = QQ^3; W = span([[1,2,3],[-1,2,5/3]], QQ) sage: phi = V.hom(matrix(QQ,3,[1..9])) We compute the image of some elements:: sage: phi(V.0) (1, 2, 3) sage: phi(V.1) (4, 5, 6) sage: phi(V.0 - 1/4*V.1) (0, 3/4, 3/2) We compute the image of a *subspace*:: sage: V = QQ^3; W = span([[1,2,3],[-1,2,5/3]], QQ) sage: phi = V.hom(matrix(QQ,3,[1..9])) sage: phi.rank() 2 sage: phi(V) Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [ 1 0 -1] [ 0 1 2] We restrict phi to W and compute the image of an element:: sage: psi = phi.restrict_domain(W) sage: psi(W.0) == phi(W.0) True sage: psi(W.1) == phi(W.1) True We compute the image of a submodule of a ZZ-module embedded in a rational vector space:: sage: V = QQ^3; W = V.span_of_basis([[2,2,3],[-1,2,5/3]], ZZ) sage: phi = W.hom([W.0, W.0-W.1]); phi Free module morphism defined by the matrix [ 1 0] [ 1 -1]... sage: phi(span([2*W.1],ZZ)) Free module of degree 3 and rank 1 over Integer Ring Echelon basis matrix: [ 6 0 8/3] sage: phi(2*W.1) (6, 0, 8/3) """ if free_module.is_FreeModule(x): V = self.domain().submodule(x) return self.restrict_domain(V).image() return matrix_morphism.MatrixMorphism.__call__(self, x)
def is_vector_space(self): """ Return whether the free module is a vector space. OUTPUT: Boolean. Whether the :meth:`free_module` factor in the tensor product is a vector space. EXAMPLES:: sage: mip = MixedIntegerLinearProgram() sage: LF = mip.linear_functions_parent() sage: LF.tensor(RDF^2).is_vector_space() True sage: LF.tensor(RDF^(2,2)).is_vector_space() False """ from sage.modules.free_module import is_FreeModule return is_FreeModule(self.free_module())
def _get_action_(self, other, op, self_is_left): """ Register actions with the coercion model. The monoid actions are Minkowski sum and cartesian product. In addition, we want multiplication by a scalar to be dilation and addition by a vector to be translation. This is implemented as an action in the coercion model. INPUT: - ``other`` -- a scalar or a vector. - ``op`` -- the operator. - ``self_is_left`` -- boolean. Whether ``self`` is on the left of the operator. OUTPUT: An action that is used by the coercion model. EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra sage: Polyhedra(ZZ,2).get_action(ZZ) # indirect doctest Right action by Integer Ring on Polyhedra in ZZ^2 sage: Polyhedra(ZZ,2).get_action(QQ) Right action by Rational Field on Polyhedra in QQ^2 with precomposition on left by Conversion map: From: Polyhedra in ZZ^2 To: Polyhedra in QQ^2 with precomposition on right by Identity endomorphism of Rational Field sage: Polyhedra(QQ,2).get_action(ZZ) Right action by Integer Ring on Polyhedra in QQ^2 sage: Polyhedra(QQ,2).get_action(QQ) Right action by Rational Field on Polyhedra in QQ^2 sage: Polyhedra(ZZ,2).an_element() * 2 A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: Polyhedra(ZZ,2).an_element() * (2/3) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: Polyhedra(QQ,2).an_element() * 2 A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: Polyhedra(QQ,2).an_element() * (2/3) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: 2 * Polyhedra(ZZ,2).an_element() A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: (2/3) * Polyhedra(ZZ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: 2 * Polyhedra(QQ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: (2/3) * Polyhedra(QQ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: from sage.geometry.polyhedron.parent import Polyhedra sage: Polyhedra(ZZ,2).get_action( ZZ^2, op=operator.add) Right action by Ambient free module of rank 2 over the principal ideal domain Integer Ring on Polyhedra in ZZ^2 with precomposition on left by Identity endomorphism of Polyhedra in ZZ^2 with precomposition on right by Generic endomorphism of Ambient free module of rank 2 over the principal ideal domain Integer Ring """ import operator from sage.structure.coerce_actions import ActedUponAction from sage.categories.action import PrecomposedAction if op is operator.add and is_FreeModule(other): base_ring = self._coerce_base_ring(other) extended_self = self.base_extend(base_ring) extended_other = other.base_extend(base_ring) action = ActedUponAction(extended_other, extended_self, not self_is_left) if self_is_left: action = PrecomposedAction( action, extended_self._internal_coerce_map_from(self).__copy__(), extended_other._internal_coerce_map_from(other).__copy__(), ) else: action = PrecomposedAction( action, extended_other._internal_coerce_map_from(other).__copy__(), extended_self._internal_coerce_map_from(self).__copy__(), ) return action if op is operator.mul and is_CommutativeRing(other): ring = self._coerce_base_ring(other) if ring is self.base_ring(): return ActedUponAction(other, self, not self_is_left) extended = self.base_extend(ring) action = ActedUponAction(ring, extended, not self_is_left) if self_is_left: action = PrecomposedAction( action, extended._internal_coerce_map_from(self).__copy__(), ring._internal_coerce_map_from(other).__copy__(), ) else: action = PrecomposedAction( action, ring._internal_coerce_map_from(other).__copy__(), extended._internal_coerce_map_from(self).__copy__(), ) return action
def _get_action_(self, other, op, self_is_left): """ Register actions with the coercion model. The monoid actions are Minkowski sum and Cartesian product. In addition, we want multiplication by a scalar to be dilation and addition by a vector to be translation. This is implemented as an action in the coercion model. INPUT: - ``other`` -- a scalar or a vector. - ``op`` -- the operator. - ``self_is_left`` -- boolean. Whether ``self`` is on the left of the operator. OUTPUT: An action that is used by the coercion model. EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra sage: PZZ2 = Polyhedra(ZZ, 2) sage: PZZ2.get_action(ZZ) # indirect doctest Right action by Integer Ring on Polyhedra in ZZ^2 sage: PZZ2.get_action(QQ) Right action by Rational Field on Polyhedra in QQ^2 with precomposition on left by Conversion map: From: Polyhedra in ZZ^2 To: Polyhedra in QQ^2 with precomposition on right by Identity endomorphism of Rational Field sage: PQQ2 = Polyhedra(QQ, 2) sage: PQQ2.get_action(ZZ) Right action by Integer Ring on Polyhedra in QQ^2 sage: PQQ2.get_action(QQ) Right action by Rational Field on Polyhedra in QQ^2 sage: Polyhedra(ZZ,2).an_element() * 2 A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: Polyhedra(ZZ,2).an_element() * (2/3) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: Polyhedra(QQ,2).an_element() * 2 A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: Polyhedra(QQ,2).an_element() * (2/3) A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: 2 * Polyhedra(ZZ,2).an_element() A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: (2/3) * Polyhedra(ZZ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: 2 * Polyhedra(QQ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: (2/3) * Polyhedra(QQ,2).an_element() A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 3 vertices sage: from sage.geometry.polyhedron.parent import Polyhedra sage: PZZ2.get_action(ZZ^2, op=operator.add) Right action by Ambient free module of rank 2 over the principal ideal domain Integer Ring on Polyhedra in ZZ^2 with precomposition on left by Identity endomorphism of Polyhedra in ZZ^2 with precomposition on right by Generic endomorphism of Ambient free module of rank 2 over the principal ideal domain Integer Ring """ import operator from sage.structure.coerce_actions import ActedUponAction from sage.categories.action import PrecomposedAction if op is operator.add and is_FreeModule(other): base_ring = self._coerce_base_ring(other) extended_self = self.base_extend(base_ring) extended_other = other.base_extend(base_ring) action = ActedUponAction(extended_other, extended_self, not self_is_left) if self_is_left: action = PrecomposedAction( action, extended_self._internal_coerce_map_from(self).__copy__(), extended_other._internal_coerce_map_from(other).__copy__()) else: action = PrecomposedAction( action, extended_other._internal_coerce_map_from(other).__copy__(), extended_self._internal_coerce_map_from(self).__copy__()) return action if op is operator.mul and is_CommutativeRing(other): ring = self._coerce_base_ring(other) if ring is self.base_ring(): return ActedUponAction(other, self, not self_is_left) extended = self.base_extend(ring) action = ActedUponAction(ring, extended, not self_is_left) if self_is_left: action = PrecomposedAction( action, extended._internal_coerce_map_from(self).__copy__(), ring._internal_coerce_map_from(other).__copy__()) else: action = PrecomposedAction( action, ring._internal_coerce_map_from(other).__copy__(), extended._internal_coerce_map_from(self).__copy__()) return action
def is_closed(self): """ Return if ``self`` is (known to be) a closed subset of the manifold. EXAMPLES:: sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback sage: M = Manifold(2, 'R^2', structure='topological') sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2 The pullback of a closed real interval under a scalar field is closed:: sage: r_squared = M.scalar_field(x^2+y^2) sage: r_squared.set_immutable() sage: cl_I = RealSet([1, 2]); cl_I [1, 2] sage: cl_O = ManifoldSubsetPullback(r_squared, cl_I); cl_O Subset f_inv_[1, 2] of the 2-dimensional topological manifold R^2 sage: cl_O.is_closed() True The pullback of a (closed convex) polyhedron under a chart is closed:: sage: P = Polyhedron(vertices=[[0, 0], [1, 2], [3, 4]]); P A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices sage: McP = ManifoldSubsetPullback(c_cart, P, name='McP'); McP Subset McP of the 2-dimensional topological manifold R^2 sage: McP.is_closed() True The pullback of real vector subspaces under a chart is closed:: sage: V = span([[1, 2]], RR); V Vector space of degree 2 and dimension 1 over Real Field with 53 bits of precision Basis matrix: [1.00000000000000 2.00000000000000] sage: McV = ManifoldSubsetPullback(c_cart, V, name='McV'); McV Subset McV of the 2-dimensional topological manifold R^2 sage: McV.is_closed() True The pullback of point lattices under a chart is closed:: sage: W = span([[1, 0], [3, 5]], ZZ); W Free module of degree 2 and rank 2 over Integer Ring Echelon basis matrix: [1 0] [0 5] sage: McW = ManifoldSubsetPullback(c_cart, W, name='McW'); McW Subset McW of the 2-dimensional topological manifold R^2 sage: McW.is_closed() True The pullback of finite sets is closed:: sage: F = Family([vector(QQ, [1, 2], immutable=True), vector(QQ, [2, 3], immutable=True)]) sage: McF = ManifoldSubsetPullback(c_cart, F, name='McF'); McF Subset McF of the 2-dimensional topological manifold R^2 sage: McF.is_closed() True """ if self.manifold().dimension() == 0: return True if isinstance(self._codomain_subset, ManifoldSubset): if self._codomain_subset.is_closed(): # known closed return True elif isinstance(self._codomain_subset, RealSet): # RealSet can decide closedness authoritatively return self._codomain_subset.is_closed() elif isinstance(self._codomain_subset, sage.geometry.abc.Polyhedron): # Regardless of their base_ring, we treat polyhedra as closed # convex subsets of R^n return True elif is_FreeModule(self._codomain_subset ) and self._codomain_subset.rank() != infinity: if self._codomain_subset.base_ring() in MetricSpaces().Complete(): # Closed topological vector subspace return True if self._codomain_subset.base_ring() == ZZ: if self._codomain_subset.coordinate_ring().is_subring(QQ): # Discrete subgroup of R^n return True if self._codomain_subset.rank( ) == self._codomain_subset.base_extend(RR).dimension(): # Discrete subgroup of R^n return True elif self._codomain_subset in Sets().Finite(): return True else: if hasattr(self._codomain_subset, 'is_topologically_closed'): try: from ppl import NNC_Polyhedron, C_Polyhedron except ImportError: pass else: if isinstance(self._codomain_subset, (NNC_Polyhedron, C_Polyhedron)): # ppl polyhedra can decide closedness authoritatively return self._codomain_subset.is_topologically_closed() return super().is_closed()