def _coerce_map_from_(self, S): r""" Coercion from a parent ``S``. There is a coercion from ``S`` if ``S`` has a coerce map to `\Q` or if `S = \Q/m\Z` for `m` a multiple of `n`. TESTS:: sage: G2 = QQ/(2*ZZ) sage: G3 = QQ/(3*ZZ) sage: G4 = QQ/(4*ZZ) sage: G2.has_coerce_map_from(QQ) True sage: G2.has_coerce_map_from(ZZ) True sage: G2.has_coerce_map_from(ZZ['x']) False sage: G2.has_coerce_map_from(G3) False sage: G2.has_coerce_map_from(G4) True sage: G4.has_coerce_map_from(G2) False """ if QQ.has_coerce_map_from(S): return True if isinstance(S, QmodnZ) and (S.n / self.n in ZZ): return True
def __add__(self, other): r""" Return the subsemigroup of `\QQ` generated by this semigroup and ``other``. INPUT: - ``other`` -- a discrete value (semi-)group or a rational number EXAMPLES:: sage: from sage.rings.valuation.value_group import DiscreteValueSemigroup, DiscreteValueGroup sage: D = DiscreteValueSemigroup(1/2) sage: D + 1/3 Additive Abelian Semigroup generated by 1/3, 1/2 sage: D + D Additive Abelian Semigroup generated by 1/2 sage: D + 1 Additive Abelian Semigroup generated by 1/2 sage: DiscreteValueGroup(2/7) + DiscreteValueSemigroup(4/9) Additive Abelian Semigroup generated by -2/7, 2/7, 4/9 """ if isinstance(other, DiscreteValueSemigroup): return DiscreteValueSemigroup(self._generators + other._generators) if isinstance(other, DiscreteValueGroup): return DiscreteValueSemigroup(self._generators + (other._generator, -other._generator)) from sage.structure.element import is_Element if is_Element(other) and QQ.has_coerce_map_from(other.parent()): return self + DiscreteValueSemigroup(other) raise ValueError( "`other` must be a DiscreteValueGroup, a DiscreteValueSemigroup or a rational number" )
def construct_from_maass_products(ring, weight, products, is_basis = True, provides_maass_spezialschar = False, is_integral = False, lazy_rank_check = True) : r""" Pass the return value of spanning_maass_products of a space of Siegel modular forms of same type. This will return a space using these forms. Whenever ``is_basis`` is False the the products are first filtered to yield a basis. """ assert QQ.has_coerce_map_from(ring.base_ring()) or ring.base_ring() is ZZ, \ "%s doesn't have rational base field" % ring dim = ring.graded_submodule(weight).dimension() ## if the products don't provide a basis, we have to choose one if not is_basis : ## we prefer to use Maass lifts, since they are very cheap maass_forms = []; non_maass_forms = [] for p in products : if len(p[0]) == 1 : maass_forms.append(p) else : non_maass_forms.append(p) monomials = set() lift_polys = [] products = [] for lifts, lift_poly in maass_forms + non_maass_forms : red_poly = ring(ring.relations().ring()(lift_poly))._reduce_polynomial() monomials = monomials.union(set(red_poly.monomials())) M = matrix( QQ, len(lift_polys) + 1, [ poly.monomial_coefficient(m) for poly in lift_polys + [lift_poly] for m in monomials] ) # TODO : Use linbox try : if magma(M).Rank() > len(lift_polys) : break except TypeError : for i in xrange(10) : Mp = matrix(Qp(random_prime(10**10), 10), M) if Mp.rank() > len(lift_polys) : break else : if lazy_rank_check : continue elif M.rank() <= len(lift_polys) : continue lift_polys.append(red_poly) products.append((lifts, red_poly)) if len(products) == dim : break else : raise ValueError, "products don't provide a basis" basis = [] if provides_maass_spezialschar : maass_form_indices = [] for i, (lifts, lift_poly) in enumerate(products) : e = ring(ring.relations().ring()(lift_poly)) if len(lifts) == 1 : l = lifts[0] e._set_fourier_expansion( SiegelModularFormG2MaassLift(l[0], l[1], ring.fourier_expansion_precision(), is_integral = is_integral) ) elif len(lifts) == 2 : (l0, l1) = tuple(lifts) e._set_fourier_expansion( EquivariantMonoidPowerSeries_LazyMultiplication( SiegelModularFormG2MaassLift(l0[0], l0[1], ring.fourier_expansion_precision(), is_integral = is_integral), SiegelModularFormG2MaassLift(l1[0], l1[1], ring.fourier_expansion_precision(), is_integral = is_integral) ) ) else : e._set_fourier_expansion( prod( SiegelModularFormG2MaassLift(l[0], l[1], ring.precision(), is_integral = is_integral) for l in lifts) ) basis.append(e) if provides_maass_spezialschar and len(lifts) == 1 : maass_form_indices.append(i) ss = ring._submodule(basis, grading_indices = (weight,), is_heckeinvariant = True) if provides_maass_spezialschar : maass_coords = [ ss([0]*i + [1] + [0]*(dim-i-1)) for i in maass_form_indices ] ss.maass_space.set_cache( SiegelModularFormG2Submodule_maassspace(ss, map(ss, maass_coords)) ) return ss
def construct_from_maass_products(ring, weight, products, is_basis=True, provides_maass_spezialschar=False, is_integral=False, lazy_rank_check=True): r""" Pass the return value of spanning_maass_products of a space of Siegel modular forms of same type. This will return a space using these forms. Whenever ``is_basis`` is False the the products are first filtered to yield a basis. """ assert QQ.has_coerce_map_from(ring.base_ring()) or ring.base_ring() is ZZ, \ "%s doesn't have rational base field" % ring dim = ring.graded_submodule(weight).dimension() ## if the products don't provide a basis, we have to choose one if not is_basis: ## we prefer to use Maass lifts, since they are very cheap maass_forms = [] non_maass_forms = [] for p in products: if len(p[0]) == 1: maass_forms.append(p) else: non_maass_forms.append(p) monomials = set() lift_polys = [] products = [] for lifts, lift_poly in maass_forms + non_maass_forms: red_poly = ring( ring.relations().ring()(lift_poly))._reduce_polynomial() monomials = monomials.union(set(red_poly.monomials())) M = matrix(QQ, len(lift_polys) + 1, [ poly.monomial_coefficient(m) for poly in lift_polys + [lift_poly] for m in monomials ]) # TODO : Use linbox try: if magma(M).Rank() > len(lift_polys): break except TypeError: for i in xrange(10): Mp = matrix(Qp(random_prime(10**10), 10), M) if Mp.rank() > len(lift_polys): break else: if lazy_rank_check: continue elif M.rank() <= len(lift_polys): continue lift_polys.append(red_poly) products.append((lifts, red_poly)) if len(products) == dim: break else: raise ValueError, "products don't provide a basis" basis = [] if provides_maass_spezialschar: maass_form_indices = [] for i, (lifts, lift_poly) in enumerate(products): e = ring(ring.relations().ring()(lift_poly)) if len(lifts) == 1: l = lifts[0] e._set_fourier_expansion( SiegelModularFormG2MaassLift( l[0], l[1], ring.fourier_expansion_precision(), is_integral=is_integral)) elif len(lifts) == 2: (l0, l1) = tuple(lifts) e._set_fourier_expansion( EquivariantMonoidPowerSeries_LazyMultiplication( SiegelModularFormG2MaassLift( l0[0], l0[1], ring.fourier_expansion_precision(), is_integral=is_integral), SiegelModularFormG2MaassLift( l1[0], l1[1], ring.fourier_expansion_precision(), is_integral=is_integral))) else: e._set_fourier_expansion( prod( SiegelModularFormG2MaassLift( l[0], l[1], ring.precision(), is_integral=is_integral) for l in lifts)) basis.append(e) if provides_maass_spezialschar and len(lifts) == 1: maass_form_indices.append(i) ss = ring._submodule(basis, grading_indices=(weight, ), is_heckeinvariant=True) if provides_maass_spezialschar: maass_coords = [ ss([0] * i + [1] + [0] * (dim - i - 1)) for i in maass_form_indices ] ss.maass_space.set_cache( SiegelModularFormG2Submodule_maassspace(ss, map(ss, maass_coords))) return ss