def __init__(self, group, base_ring, k, ep, n): r""" Return the zero Module for the zero form of weight ``k`` with multiplier ``ep`` for the given ``group`` and ``base_ring``. The ZeroForm space coerces into any forms space or ring with a compatible group. EXAMPLES:: sage: from sage.modular.modform_hecketriangle.space import ZeroForm sage: MF = ZeroForm(6, CC, 3, -1) sage: MF ZeroForms(n=6, k=3, ep=-1) over Complex Field with 53 bits of precision sage: MF.analytic_type() zero sage: MF.category() Category of vector spaces over Complex Field with 53 bits of precision sage: MF in MF.category() True sage: MF.module() Vector space of dimension 0 over Fraction Field of Univariate Polynomial Ring in d over Complex Field with 53 bits of precision sage: MF.ambient_module() == MF.module() True sage: MF.is_ambient() True """ FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) self._analytic_type=self.AT([]) self._module = FreeModule(self.coeff_ring(), self.dimension())
def ambient_module(self): """ Return the ambient module. .. SEEALSO:: :meth:`ambient_vector_space` OUTPUT: The domain of the linear expressions as a free module over the base ring. EXAMPLES:: sage: from sage.geometry.linear_expression import LinearExpressionModule sage: L = LinearExpressionModule(QQ, ('x', 'y', 'z')) sage: L.ambient_module() Vector space of dimension 3 over Rational Field sage: M = LinearExpressionModule(ZZ, ('r', 's')) sage: M.ambient_module() Ambient free module of rank 2 over the principal ideal domain Integer Ring sage: M.ambient_vector_space() Vector space of dimension 2 over Rational Field """ from sage.modules.free_module import FreeModule return FreeModule(self.base_ring(), self.ngens())
def Vrepresentation_space(self): r""" Return the ambient vector space. This is the vector space or module containing the Vrepresentation vectors. OUTPUT: A free module over the base ring of dimension :meth:`ambient_dim`. EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra sage: Polyhedra(QQ, 4).Vrepresentation_space() Vector space of dimension 4 over Rational Field sage: Polyhedra(QQ, 4).ambient_space() Vector space of dimension 4 over Rational Field """ if self.base_ring() in Fields(): from sage.modules.free_module import VectorSpace return VectorSpace(self.base_ring(), self.ambient_dim()) else: from sage.modules.free_module import FreeModule return FreeModule(self.base_ring(), self.ambient_dim())
def __classcall_private__(cls, R, n=None, M=None, ambient=None): """ Normalize input to ensure a unique representation. EXAMPLES:: sage: from sage.categories.examples.finite_dimensional_lie_algebras_with_basis import AbelianLieAlgebra sage: A1 = AbelianLieAlgebra(QQ, n=3) sage: A2 = AbelianLieAlgebra(QQ, M=FreeModule(QQ, 3)) sage: A3 = AbelianLieAlgebra(QQ, 3, FreeModule(QQ, 3)) sage: A1 is A2 and A2 is A3 True sage: A1 = AbelianLieAlgebra(QQ, 2) sage: A2 = AbelianLieAlgebra(ZZ, 2) sage: A1 is A2 False sage: A1 = AbelianLieAlgebra(QQ, 0) sage: A2 = AbelianLieAlgebra(QQ, 1) sage: A1 is A2 False """ if M is None: M = FreeModule(R, n) else: M = M.change_ring(R) n = M.dimension() return super(AbelianLieAlgebra, cls).__classcall__(cls, R, n=n, M=M, ambient=ambient)
def __init__(self, group, base_ring, k, ep, n): r""" Return the Module of (Hecke) quasi cusp forms of weight ``k`` with multiplier ``ep`` for the given ``group`` and ``base_ring``. EXAMPLES:: sage: from sage.modular.modform_hecketriangle.space import QuasiCuspForms sage: MF = QuasiCuspForms(8, ZZ, 16/3) sage: MF QuasiCuspForms(n=8, k=16/3, ep=1) over Integer Ring sage: MF.analytic_type() quasi cuspidal sage: MF.category() Category of modules over Integer Ring sage: MF in MF.category() True sage: MF.is_ambient() True sage: QuasiCuspForms(n=infinity) QuasiCuspForms(n=+Infinity, k=0, ep=1) over Integer Ring """ FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) self._analytic_type=self.AT(["quasi", "cusp"]) self._module = FreeModule(self.coeff_ring(), self.dimension())
def __init__(self, group, base_ring, k, ep, n): r""" Return the Module of (Hecke) modular forms of weight ``k`` with multiplier ``ep`` for the given ``group`` and ``base_ring``. EXAMPLES:: sage: from sage.modular.modform_hecketriangle.space import ModularForms sage: MF = ModularForms() sage: MF ModularForms(n=3, k=0, ep=1) over Integer Ring sage: MF.analytic_type() modular sage: MF.category() Category of vector spaces over Fraction Field of Univariate Polynomial Ring in d over Integer Ring sage: MF.module() Vector space of dimension 1 over Fraction Field of Univariate Polynomial Ring in d over Integer Ring sage: MF.ambient_module() == MF.module() True sage: MF.is_ambient() True sage: MF = ModularForms(n=infinity, k=8) sage: MF ModularForms(n=+Infinity, k=8, ep=1) over Integer Ring sage: MF.analytic_type() modular sage: MF.category() Category of vector spaces over Fraction Field of Univariate Polynomial Ring in d over Integer Ring """ FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=self.coeff_ring()) self._analytic_type = self.AT(["holo"]) self._module = FreeModule(self.coeff_ring(), self.dimension())
def _dense_free_module(self, base_ring=None): """ Return a dense free module of the same dimension as ``self``. INPUT: - ``base_ring`` -- a ring or ``None`` If ``base_ring`` is ``None``, then the base ring of ``self`` is used. This method is mostly used by ``_vector_`` EXAMPLES:: sage: C = CombinatorialFreeModule(QQ['x'], ['a','b','c']); C Free module generated by {'a', 'b', 'c'} over Univariate Polynomial Ring in x over Rational Field sage: C._dense_free_module() Ambient free module of rank 3 over the principal ideal domain Univariate Polynomial Ring in x over Rational Field sage: C._dense_free_module(QQ['x,y']) Ambient free module of rank 3 over the integral domain Multivariate Polynomial Ring in x, y over Rational Field """ if base_ring is None: base_ring = self.base_ring() from sage.modules.free_module import FreeModule return FreeModule(base_ring, self.dimension())
def _vector_(self, R=None): r""" Return Sage vector from this octave element. EXAMPLES:: sage: A = octave('[1,2,3,4]') # optional - octave sage: vector(ZZ, A) # optional - octave (1, 2, 3, 4) sage: A = octave('[1,2.3,4.5]') # optional - octave sage: vector(A) # optional - octave (1.0, 2.3, 4.5) sage: A = octave('[1,I]') # optional - octave sage: vector(A) # optional - octave (1.0, 1.0*I) """ oc = self.parent() if not self.isvector(): raise TypeError('not an octave vector') if R is None: R = self._get_sage_ring() s = str(self).strip('\n ') w = s.strip().split(' ') nrows = len(w) if self.iscomplex(): w = [to_complex(x, R) for x in w] from sage.modules.free_module import FreeModule return FreeModule(R, nrows)(w)
def finite_direct_sum_of_constant_family(I, R, M): '''Given a finite set I, and a FreeModule M over a ring R, returns the copower M^{(I)} = \bigoplus_{i \in I} M. More precisely, returns a triple (N, components, from_components), where N - instance of FreeModule components - function that given an element n of N, returns a dict { i: i-th component of m } from_components - function that given a dict { i: n[i] }, returns an element n of N such that n[i] is the i-th component of N ''' assert isinstance(M, FreeModule_generic) m = len(M.gens()) assert m == M.rank() index_to_I = list(I) len_I = len(index_to_I) N = FreeModule(R, len_I * m) I_to_index = {} for k in range(len_I): I_to_index[index_to_I[k]] = k def components(x): return { i: M.linear_combination_of_basis(x[m * I_to_index[i]:m * (I_to_index[i] + 1)]) for i in I } def from_components(comp): return N.linear_combination_of_basis( list( chain.from_iterable((M.coordinate_vector(comp[i]) if i in comp.keys() else M.zero_vector() for i in I)))) return (N, components, from_components)
def __init__(self, group, base_ring, k, ep, n): r""" Return the Module of (Hecke) cusp forms of weight ``k`` with multiplier ``ep`` for the given ``group`` and ``base_ring``. EXAMPLES:: sage: from sage.modular.modform_hecketriangle.space import CuspForms sage: MF = CuspForms(6, ZZ, 6, 1) sage: MF CuspForms(n=6, k=6, ep=1) over Integer Ring sage: MF.analytic_type() cuspidal sage: MF.category() Category of modules over Integer Ring sage: MF in MF.category() True sage: MF.module() Vector space of dimension 1 over Fraction Field of Univariate Polynomial Ring in d over Integer Ring sage: MF.ambient_module() == MF.module() True sage: MF.is_ambient() True """ FormsSpace_abstract.__init__(self, group=group, base_ring=base_ring, k=k, ep=ep, n=n) Module.__init__(self, base=base_ring) self._analytic_type=self.AT(["cusp"]) self._module = FreeModule(self.coeff_ring(), self.dimension())
def __init__(self, R): self.R = R # don't really need to keep this, but might as well self.Pvee = R.coweight_lattice() basis = self.Pvee.basis() basis_keys = tuple(basis.keys()) dim = len(basis_keys) self.MPvee = FreeModule(ZZ, dim) self.MQvee = self.MPvee.submodule([ vector([alpha_vee[j] for j in basis_keys]) for alpha_vee in self.Pvee.simple_roots() ]) self.fundamental_group = self.MPvee / self.MQvee def Pvee_to_MPvee(x): return vector([x[k] for k in basis_keys ]) # using x[k] is way faster than x.coefficient(k) def MPvee_to_Pvee(x): return sum_in_module( self.Pvee, [x[i] * basis[basis_keys[i]] for i in range(dim)]) def action52(g, x): return Pvee_to_MPvee(g.action(MPvee_to_Pvee(x))) self.action = action52 self.Pvee_to_MPvee = Pvee_to_MPvee self.MPvee_to_Pvee = MPvee_to_Pvee
def _iterate_PointCollection(self, start, stop, step): """ Iterate over the reflexive polytopes. INPUT: - ``start``, ``stop``, ``step`` -- integers specifying the range to iterate over. OUTPUT: A generator for PPL-based lattice polyhedra. EXAMPLES:: sage: from sage.geometry.polyhedron.palp_database import PALPreader sage: polygons = PALPreader(2) sage: iter = polygons._iterate_PointCollection(0,4,2) sage: next(iter) [ 1, 0], [ 0, 1], [-1, -1] in Ambient free module of rank 2 over the principal ideal domain Integer Ring """ from sage.modules.free_module import FreeModule N = FreeModule(ZZ, self._dim) from sage.geometry.point_collection import PointCollection for vertices in self._iterate_list(start, stop, step): yield PointCollection(vertices, module=N)
def __init__(self, vertices=None, edges=None, faces=None, holonomies=None): r = RibbonGraph(vertices,edges,faces) RibbonGraph.__init__(self,r.vertex_perm(),r.edge_perm(),r.face_perm()) if len(holonomies) != self.num_darts(): raise ValueError("there are %d angles and %d darts" %(len(angles),self.num_darts())) V = FreeModule(ZZ, 2) self._holonomies = list(map(V, holonomies))
def module(self, sparse=True): """ Return ``self`` as a free module. EXAMPLES:: sage: L.<x,y,z> = LieAlgebra(QQ, {('x','y'):{'z':1}}) sage: L.module() Sparse vector space of dimension 3 over Rational Field """ return FreeModule(self.base_ring(), self.dimension(), sparse=sparse)
def __init__(self, poly_ring): from sage.modules.free_module import FreeModule self._polynomial_ring = poly_ring dim = ZZ(poly_ring.ngens()) self._free_module = FreeModule(ZZ, dim) # univariate extension of the polynomial ring # (needed in several algorithms) self._polynomial_ring_extra_var = self._polynomial_ring['EXTRA_VAR'] Parent.__init__(self, category=Rings(), base=poly_ring.base_ring())
def positive_roots(self, as_reflections=False): """ Return the positive roots. These are roots in the Coxeter sense, that all have the same norm. They are given by their coefficients in the base of simple roots, also taken to have all the same norm. This can also be used to obtain the associated reflections. .. SEEALSO:: :meth:`reflections` EXAMPLES:: sage: W = CoxeterGroup(['A',3], implementation='reflection') sage: W.positive_roots() [(1, 0, 0), (1, 1, 0), (0, 1, 0), (1, 1, 1), (0, 1, 1), (0, 0, 1)] sage: W = CoxeterGroup(['I',5], implementation='reflection') sage: W.positive_roots() [(1, 0), (-E(5)^2 - E(5)^3, 1), (-E(5)^2 - E(5)^3, -E(5)^2 - E(5)^3), (1, -E(5)^2 - E(5)^3), (0, 1)] """ if not self.is_finite(): raise NotImplementedError('not available for infinite groups') word = self.long_element(as_word=True) N = len(word) if not as_reflections: from sage.modules.free_module import FreeModule simple_roots = FreeModule(self.base_ring(), self.ngens()).gens() refls = self.simple_reflections() resu = [] for i in range(1, N + 1): segment = word[:i] if as_reflections: rt = refls[segment.pop()] else: rt = simple_roots[segment.pop() - 1] while segment: if as_reflections: cr = refls[segment.pop()] rt = cr * rt * cr else: rt = refls[segment.pop()] * rt resu += [rt] return resu
def base_change_module(M, R): assert R.has_coerce_map_from(M.base_ring()) MM = FreeModule(R, len(M.basis())) # given an element x of M, returns the image of x in MM under the canonical map # M ---> MM = M \otimes_{R'} R def base_change_map(x): return MM.from_vector( vector(map(R.coerce_map_from(M.base_ring()), M.coordinates(x)))) MM.base_change_map = base_change_map return MM
def matrix(self): V = FreeModule(ZZ, len(self._start)) columns = [copy(v) for v in V.basis()] for p, winner, side in self: winner_letter = p._labels[winner][side] loser_letter = p._labels[1 - winner][side] columns[loser_letter] += columns[winner_letter] m = MatrixSpace(ZZ, len(p))(columns).transpose() perm_on_list_inplace(self._relabelling, m, swap=sage.matrix.matrix0.Matrix.swap_columns) return m
def __init__(self, toric_variety, base_ring, check): r""" EXAMPLES:: sage: from sage.schemes.toric.chow_group import * sage: P2=toric_varieties.P2() sage: A = ChowGroup_class(P2,ZZ,True); A Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches sage: is_ChowGroup(A) True sage: is_ChowCycle(A.an_element()) True TESTS:: sage: A_ZZ = P2.Chow_group() sage: 2 * A_ZZ.an_element() * 3 ( 6 | 0 | 0 ) sage: 1/2 * A_ZZ.an_element() * 1/3 Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'Rational Field' and 'Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches' sage: coercion_model.get_action(A_ZZ, ZZ) Right scalar multiplication by Integer Ring on Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches sage: print(coercion_model.get_action(A_ZZ, QQ)) None You can't multiply integer classes with fractional numbers. For that you need to go to the rational Chow group:: sage: A_QQ = P2.Chow_group(QQ) sage: 2 * A_QQ.an_element() * 3 ( 0 | 0 | 6 ) sage: 1/2 * A_QQ.an_element() * 1/3 ( 0 | 0 | 1/6 ) sage: coercion_model.get_action(A_QQ, ZZ) Right scalar multiplication by Integer Ring on QQ-Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches sage: coercion_model.get_action(A_QQ, QQ) Right scalar multiplication by Rational Field on QQ-Chow group of 2-d CPR-Fano toric variety covered by 3 affine patches """ self._variety = toric_variety # cones are automatically sorted by dimension self._cones = flatten(toric_variety.fan().cones()) V = FreeModule(base_ring, len(self._cones)) W = self._rational_equivalence_relations(V) super(ChowGroup_class, self).__init__(V, W, check)
def faster_kernel(f): '''Computes the kernel of a morphism between FreeModules. Until this is fixed in Sage, it is necessary if we want to compute kernels of integer matrices in our lifetime. ''' if f.base_ring() == ZZ: K = f.matrix().change_ring(QQ).kernel().intersection( FreeModule(ZZ, f.domain().rank())) return f.domain().submodule( [f.domain().linear_combination_of_basis(x) for x in K.gens()]) else: return f.kernel()
def __init__(self, R, form, names=None): """ Initialize ``self``. TESTS:: sage: m = matrix([[-2,3],[3,4]]) sage: J = JordanAlgebra(m) sage: TestSuite(J).run() """ self._form = form self._M = FreeModule(R, form.ncols()) cat = MagmaticAlgebras(R).Commutative().Unital().FiniteDimensional().WithBasis() Parent.__init__(self, base=R, names=names, category=cat)
def _dense_free_module(self, R=None): """ Return a dense free module associated to ``self`` over ``R``. EXAMPLES:: sage: L = LieAlgebras(QQ).FiniteDimensional().WithBasis().example() sage: L._dense_free_module() Vector space of dimension 3 over Rational Field """ if R is None: R = self.base_ring() from sage.modules.free_module import FreeModule return FreeModule(R, self.dimension())
def reduce_basis(self, long_etas): r""" Produce a more manageable basis via LLL-reduction. INPUT: - ``long_etas`` - a list of EtaGroupElement objects (which should all be of the same level) OUTPUT: - a new list of EtaGroupElement objects having hopefully smaller norm ALGORITHM: We define the norm of an eta-product to be the `L^2` norm of its divisor (as an element of the free `\ZZ`-module with the cusps as basis and the standard inner product). Applying LLL-reduction to this gives a basis of hopefully more tractable elements. Of course we'd like to use the `L^1` norm as this is just twice the degree, which is a much more natural invariant, but `L^2` norm is easier to work with! EXAMPLES:: sage: EtaGroup(4).reduce_basis([ EtaProduct(4, {1:8,2:24,4:-32}), EtaProduct(4, {1:8, 4:-8})]) [Eta product of level 4 : (eta_1)^8 (eta_4)^-8, Eta product of level 4 : (eta_1)^-8 (eta_2)^24 (eta_4)^-16] """ from six.moves import range N = self.level() cusps = AllCusps(N) r = matrix(ZZ, [[et.order_at_cusp(c) for c in cusps] for et in long_etas]) V = FreeModule(ZZ, r.ncols()) A = V.submodule_with_basis([V(rw) for rw in r.rows()]) rred = r.LLL() short_etas = [] for shortvect in rred.rows(): bv = A.coordinates(shortvect) dict = { d: sum(bv[i] * long_etas[i].r(d) for i in range(r.nrows())) for d in divisors(N) } short_etas.append(self(dict)) return short_etas
def __init__(self, degrees): r""" INPUT: - ``degrees`` -- A list or tuple of `n` positive integers. TESTS:: sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import * sage: g = DegreeGrading((1,2)) sage: g = DegreeGrading([5,2,3]) """ self.__degrees = tuple(degrees) self.__module = FreeModule(ZZ, len(degrees)) self.__module_basis = self.__module.basis()
def __init__(self, R, s_coeff, names, index_set, category=None, prefix=None, bracket=None, latex_bracket=None, string_quotes=None, **kwds): """ Initialize ``self``. EXAMPLES:: sage: L = LieAlgebra(QQ, 'x,y', {('x','y'): {'x':1}}) sage: TestSuite(L).run() """ default = (names != tuple(index_set)) if prefix is None: if default: prefix = 'L' else: prefix = '' if bracket is None: bracket = default if latex_bracket is None: latex_bracket = default if string_quotes is None: string_quotes = default #self._pos_to_index = dict(enumerate(index_set)) self._index_to_pos = {k: i for i,k in enumerate(index_set)} if "sorting_key" not in kwds: kwds["sorting_key"] = self._index_to_pos.__getitem__ cat = LieAlgebras(R).WithBasis().FiniteDimensional().or_subcategory(category) FinitelyGeneratedLieAlgebra.__init__(self, R, names, index_set, cat) IndexedGenerators.__init__(self, self._indices, prefix=prefix, bracket=bracket, latex_bracket=latex_bracket, string_quotes=string_quotes, **kwds) self._M = FreeModule(R, len(index_set)) # Transform the values in the structure coefficients to elements def to_vector(tuples): vec = [R.zero()]*len(index_set) for k,c in tuples: vec[self._index_to_pos[k]] = c vec = self._M(vec) vec.set_immutable() return vec self._s_coeff = {(self._index_to_pos[k[0]], self._index_to_pos[k[1]]): to_vector(s_coeff[k]) for k in s_coeff.keys()}
def __call__(self, M): S = self.domain() # = plaintext_space = ciphertext_space if not isinstance(M, StringMonoidElement) and M.parent() == S: raise TypeError("Argument M (= %s) must be a string in the plaintext space." % M) m = self.parent().block_length() if len(M) % m != 0: raise TypeError("The length of M (= %s) must be a multiple of %s." % (M, m )) Alph = list(S.alphabet()) A = self.key() # A is an m x m matrix R = A.parent().base_ring() V = FreeModule(R,m) Mstr = str(M) C = [] for i in range(len(M)//m): v = V([ Alph.index(Mstr[m*i+j]) for j in range(m) ]) C += (v * A).list() return S([ k.lift() for k in C ])
def __init__(self, K, additive=True, dlog=True): Parent.__init__(self) self._additive = additive self._dlog = dlog self._base_ring = K self._prec = K.precision_cap() psprec = self._prec + 1 if dlog else self._prec self._Ps = PowerSeriesRing(self._base_ring, names='t', default_prec=psprec) if self._additive: self._V = FreeModule(K, self._prec) t = self._Ps.gen() self._Ps_local_variable = lambda Q: 1 - t / Q self._unset_coercions_used() self.register_action(Scaling(ZZ, self)) self.register_action(MatrixAction(MatrixSpace(K, 2, 2), self))
def ambient_space(self): r""" Return the ambient space. OUTPUT: The free module `\ZZ^d`, where `d` is the ambient space dimension. EXAMPLES:: sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL sage: point = LatticePolytope_PPL((1,2,3)) sage: point.ambient_space() Ambient free module of rank 3 over the principal ideal domain Integer Ring """ from sage.modules.free_module import FreeModule return FreeModule(ZZ, self.space_dimension())
def _positive_roots_reflections(self): """ Return a family whose keys are the positive roots and values are the reflections. EXAMPLES:: sage: W = CoxeterGroup(['A', 2]) sage: F = W._positive_roots_reflections() sage: F.keys() [(1, 0), (1, 1), (0, 1)] sage: list(F) [ [-1 1] [ 0 -1] [ 1 0] [ 0 1], [-1 0], [ 1 -1] ] """ if not self.is_finite(): raise NotImplementedError('not available for infinite groups') word = self.long_element(as_word=True) N = len(word) from sage.modules.free_module import FreeModule simple_roots = FreeModule(self.base_ring(), self.ngens()).gens() refls = self.simple_reflections() resu = [] d = {} for i in range(1, N + 1): segment = word[:i] last = segment.pop() ref = refls[last] rt = simple_roots[last - 1] while segment: last = segment.pop() cr = refls[last] ref = cr * ref * cr rt = refls[last] * rt rt.set_immutable() resu += [rt] d[rt] = ref from sage.sets.family import Family return Family(resu, lambda rt: d[rt])
def Hrepresentation_space(self): r""" Return the linear space containing the H-representation vectors. OUTPUT: A free module over the base ring of dimension :meth:`ambient_dim` + 1. EXAMPLES:: sage: from sage.geometry.polyhedron.parent import Polyhedra sage: Polyhedra(ZZ, 2).Hrepresentation_space() Ambient free module of rank 3 over the principal ideal domain Integer Ring """ if self.base_ring() in Fields(): from sage.modules.free_module import VectorSpace return VectorSpace(self.base_ring(), self.ambient_dim() + 1) else: from sage.modules.free_module import FreeModule return FreeModule(self.base_ring(), self.ambient_dim() + 1)