def __init__(self, domain, sub, quotient_matrix, lift_matrix, inner_product_matrix=None): """ Create this quotient space, from the given domain, sub-module, and quotient_matrix. EXAMPLES:: sage: A = QQ^5; V = A.span_of_basis([[1,0,-1,1,1], [1,-1,0,2/3,3/4]]); V Vector space of degree 5 and dimension 2 over Rational Field User basis matrix: [ 1 0 -1 1 1] [ 1 -1 0 2/3 3/4] sage: W = V.span_of_basis([V.0 - 2/3*V.1]); W Vector space of degree 5 and dimension 1 over Rational Field User basis matrix: [1/3 2/3 -1 5/9 1/2] This creates a quotient vector space, which calls the init method:: sage: Q = V / W #indirect doctest Behold the type of Q:: sage: type(Q) <class 'sage.modules.quotient_module.FreeModule_ambient_field_quotient_with_category'> We do some consistency checks on the extra quotient and lifting structure of Q:: sage: Q(V.0) (1) sage: Q( V.0 - 2/3*V.1 ) (0) sage: v = Q.lift(Q.0); v (1, 0, -1, 1, 1) sage: Q( v ) (1) """ base_field = domain.base_field() dimension = quotient_matrix.ncols() sparse = domain.is_sparse() self.__sub = sub self.__domain = domain self.__hash = hash((domain, sub)) FreeModule_ambient_field.__init__(self, base_field, dimension, sparse) self.__quo_map = domain.Hom(self)(quotient_matrix) self.__quo_map.register_as_coercion() self.__lift_map = self.Hom(domain)(lift_matrix)
def __call__(self, x): """ Coerce an element into this quotient space V/W if there is a way to make sense of it. An element coerces in if it can be coerced into V, or if not at least if if it can be made sense of as a list of length the dimension of self. EXAMPLES: We create a 2-dimensional quotient of a 3-dimension ambient vector space. sage: M = QQ^3 / [[1,2,3]] A list of length 3 coerces into QQ^3, so it coerces into M. sage: M([1,2,4]) (-1/3, -2/3) sage: M([1,2,3]) (0, 0) A list of length 2 at least coerces into M, where here it just gives the corresponding linear combination of the basis for M. sage: M([1,2]) (1, 2) sage: M.0 + 2*M.1 (1, 2) """ try: if x.parent() is self: return x except AttributeError: pass try: return FreeModule_ambient_field.__call__(self, x) except TypeError: pass return self._coerce_impl(self.__domain(x))
def __init__(self, domain, sub, quotient_matrix, lift_matrix, inner_product_matrix = None): """ Create this quotient space, from the given domain, sub-module, and quotient_matrix. EXAMPLES:: sage: A = QQ^5; V = A.span_of_basis([[1,0,-1,1,1], [1,-1,0,2/3,3/4]]); V Vector space of degree 5 and dimension 2 over Rational Field User basis matrix: [ 1 0 -1 1 1] [ 1 -1 0 2/3 3/4] sage: W = V.span_of_basis([V.0 - 2/3*V.1]); W Vector space of degree 5 and dimension 1 over Rational Field User basis matrix: [1/3 2/3 -1 5/9 1/2] This creates a quotient vector space, which calls the init method:: sage: Q = V / W #indirect doctest Behold the type of Q:: sage: type(Q) <class 'sage.modules.quotient_module.FreeModule_ambient_field_quotient_with_category'> We do some consistency checks on the extra quotient and lifting structure of Q:: sage: Q(V.0) (1) sage: Q( V.0 - 2/3*V.1 ) (0) sage: v = Q.lift(Q.0); v (1, 0, -1, 1, 1) sage: Q( v ) (1) """ base_field = domain.base_field() dimension = quotient_matrix.ncols() sparse = domain.is_sparse() self.__sub = sub self.__domain = domain self.__hash = hash((domain, sub)) FreeModule_ambient_field.__init__(self, base_field, dimension, sparse) self.__quo_map = domain.Hom(self)(quotient_matrix) self.__quo_map.register_as_coercion() self.__lift_map = self.Hom(domain)(lift_matrix)
def _element_constructor_(self, x): """ Convert an element into this quotient space `V/W` if there is a way to make sense of it. An element converts into self if it can be converted into `V`, or if not at least if it can be made sense of as a list of length the dimension of self. EXAMPLES: We create a 2-dimensional quotient of a 3-dimension ambient vector space:: sage: M = QQ^3 / [[1,2,3]] A list of length 3 converts into ``QQ^3``, so it converts into `M`:: sage: M([1,2,4]) #indirect doctest (-1/3, -2/3) sage: M([1,2,3]) (0, 0) A list of length 2 converts into M, where here it just gives the corresponding linear combination of the basis for `M`:: sage: M([1,2]) (1, 2) sage: M.0 + 2*M.1 (1, 2) Of course, elements of ``QQ^3`` convert into the quotient module as well. Here is a different example:: sage: V = QQ^3; W = V.span([[1,0,0]]); Q = V/W sage: Q(V.0) (0, 0) sage: Q(V.1) (1, 0) sage: Q.0 (1, 0) sage: Q.0 + V.1 (2, 0) Here we start with something that is over ZZ, so it canonically coerces into ``QQ^3``, hence into ``self``:: sage: Q((ZZ^3)([1,2,3])) (2, 3) """ if isinstance(x, self.element_class) and x.parent() is self: return x if isinstance(x, (list, tuple)) and len(x) == self.__domain.rank(): return self.__quo_map(self.__domain(x)) return FreeModule_ambient_field._element_constructor_(self, x)