def __init__(self, k, p=None, prec_cap=None, base=None, symk=None, character=None, act_on_left=False): #what does symk do? """ See ``DistributionsSpace`` for full documentation. """ Parent.__init__(self,category=MSCoefficientModule) Element = DistributionElementPy #do we want elements to be DistributionElementPy or DistributionElementBase k = ZZ(k) if p is None: try: p = base.prime() except AttributeError: raise ValueError("You must specify a prime") else: p = ZZ(p) if base is None: if prec_cap is None: base = ZpCA(p) else: base = ZpCA(p, prec_cap) if prec_cap is None: try: prec_cap = base.precision_cap() except AttributeError: raise ValueError("You must specify a base or precision cap") return (k, p, prec_cap, base, character, tuplegen, act_on_left, symk)
def __init__(self, k, p=None, prec_cap=20, base=None, character=None, tuplegen=None, act_on_left=False): """ - ``character`` -- - None (default) - (chi, None) - (None, n) (n integral) - (chi, n) - lambda (for n half-integral use this form) """ if p is not None: p = ZZ(p) if base is None: if p is None: raise ValueError("specify p or a base") base = ZpCA(p,prec_cap) elif isinstance(base, pAdicGeneric): if base.prime() != p: raise ValueError("p must be the same as the prime of base") if base.precision_cap() != prec_cap: raise ValueError("prec_cap must match the precision cap of base") elif prec_cap > k+1: # non-classical if p is None or not p.is_prime(): raise ValueError("p must be prime for non-classical weight") from sage.rings.padics.pow_computer import PowComputer_long # should eventually be the PowComputer on ZpCA once that uses longs. Dist, WeightKAction = get_dist_classes(p, prec_cap, base) self.Element = Dist if Dist is Dist_long: self.prime_pow = PowComputer_long(p, prec_cap, prec_cap, prec_cap, 0) Parent.__init__(self, base) self._k = k self._p = p self._prec_cap = prec_cap act = WeightKAction(self, character, tuplegen, act_on_left) self._act = act self._populate_coercion_lists_(action_list=[act])
def create_key(self, k, p=None, prec_cap=None, base=None, \ character=None, adjuster=None, act_on_left=False, \ dettwist=None): k = ZZ(k) if base is None: if p is None: raise ValueError("Must specify a prime or a base ring.") if prec_cap is None: base = ZpCA(p) else: base = ZpCA(p, prec_cap) if prec_cap is None: prec_cap = base.precision_cap() elif prec_cap > base.precision_cap(): raise ValueError("Insufficient precision in base ring (%s < %s)." % (base.precision_cap(), prec_cap)) if p is None: p = base.prime() elif p != base.prime(): raise ValueError( "Prime p(=%s) must equal the prime of the base ring(=%s)" % (p, base.prime())) if adjuster is None: adjuster = _default_adjuster() if dettwist is not None: dettwist = ZZ(dettwist) if dettwist == 0: dettwist = None return (k, p, prec_cap, base, character, adjuster, act_on_left, dettwist)
def create_key(self, k, p=None, prec_cap=None, base=None, symk=None, character=None, tuplegen=None, act_on_left=False): """ EXAMPLES:: sage: from sage.modular.pollack_stevens.distributions import Distributions sage: Distributions(20, 3, 10) # indirect doctest Space of 3-adic distributions with k=20 action and precision cap 10 sage: TestSuite(Distributions).run() """ k = ZZ(k) if tuplegen is None: tuplegen = _default_tuplegen() if p is None: try: p = base.prime() except AttributeError: raise ValueError("You must specify a prime") else: p = ZZ(p) if base is None: if prec_cap is None: base = ZpCA(p) else: base = ZpCA(p, prec_cap) if prec_cap is None: try: prec_cap = base.precision_cap() except AttributeError: raise ValueError("You must specify a base or precision cap") return (k, p, prec_cap, base, character, tuplegen, act_on_left, symk)
def create_key( self, k, p=None, prec_cap=None, base=None, character=None, adjuster=None, act_on_left=False, dettwist=None, act_padic=False, implementation=None, ): """ EXAMPLES:: sage: from sage.modular.pollack_stevens.distributions import OverconvergentDistributions sage: OverconvergentDistributions(20, 3, 10) # indirect doctest Space of 3-adic distributions with k=20 action and precision cap 10 sage: TestSuite(OverconvergentDistributions).run() """ k = ZZ(k) if p is None: try: p = base.prime() except AttributeError: raise ValueError("You must specify a prime") else: p = ZZ(p) if base is None: if prec_cap is None: base = ZpCA(p) else: base = ZpCA(p, prec_cap) if prec_cap is None: try: prec_cap = base.precision_cap() except AttributeError: raise ValueError("You must specify a base or precision cap") if adjuster is None: adjuster = _default_adjuster() if dettwist is not None: dettwist = ZZ(dettwist) if dettwist == 0: dettwist = None return (k, p, prec_cap, base, character, adjuster, act_on_left, dettwist, act_padic, implementation)
def create_key(self, k, p=None, prec_cap=None, base=None, character=None, adjuster=None, act_on_left=False, dettwist=None, act_padic=False, implementation=None): """ EXAMPLES:: sage: from sage.modular.pollack_stevens.distributions import OverconvergentDistributions sage: OverconvergentDistributions(20, 3, 10) # indirect doctest Space of 3-adic distributions with k=20 action and precision cap 10 sage: TestSuite(OverconvergentDistributions).run() """ k = ZZ(k) if p is None: try: p = base.prime() except AttributeError: raise ValueError("You must specify a prime") else: p = ZZ(p) if base is None: if prec_cap is None: base = ZpCA(p) else: base = ZpCA(p, prec_cap) if prec_cap is None: try: prec_cap = base.precision_cap() except AttributeError: raise ValueError("You must specify a base or precision cap") if adjuster is None: adjuster = _default_adjuster() if dettwist is not None: dettwist = ZZ(dettwist) if dettwist == 0: dettwist = None return (k, p, prec_cap, base, character, adjuster, act_on_left, dettwist, act_padic, implementation)
def get_action_data(self, g, K=None): a, b, c, d = g.list() prec = self._prec if K is None: if hasattr(a, 'lift'): a, b, c, d = a.lift(), b.lift(), c.lift(), d.lift() p = g.parent().base_ring().prime() K = ZpCA(p, prec) else: K = g.parent().base_ring() Ps = PowerSeriesRing(K, 't', default_prec=prec) z = Ps.gen() zz = (d * z - b) / (-c * z + a) zz_ps0 = Ps(zz).add_bigoh(prec) if self._dlog: zz_ps = ((a * d - b * c) * (-c * z + a)**-2).add_bigoh(prec) else: zz_ps = Ps(1).add_bigoh(prec) if self.is_additive(): M = Matrix(ZZ, prec, prec, 0) for j in range(prec): for i, aij in enumerate(zz_ps.list()): M[i, j] = aij if j < prec - 1: # Don't need the last multiplication zz_ps = (zz_ps0 * zz_ps).add_bigoh(prec) else: return M else: ans = [Ps(1), zz_ps] for _ in range(prec - 1): zz_ps = (zz_ps0 * zz_ps).add_bigoh(prec) ans.append(zz_ps) return ans
def __init__(self, p, depth, act_on_left=False, adjuster=None): self._dimension = 0 ## Hack!! Dimension was being called before it was intialised self._Rmod = ZpCA(p, depth - 1) ## create Zp Module.__init__(self, base=self._Rmod) self.Element = BianchiDistributionElement self._R = ZZ self._p = p self._depth = depth self._pN = self._p**(depth - 1) self._cache_powers = dict() self._unset_coercions_used() ## Initialise monoid Sigma_0(p) + action; use Pollack-Stevens modular symbol code ## our_adjuster() is set above to allow different conventions if adjuster is None: adjuster = _default_adjuster() self._adjuster = adjuster ## Power series ring for representing distributions as strings self._repr_R = PowerSeriesRing(self._R, num_gens=2, default_prec=self._depth, names='X,Y') self._Sigma0Squared = Sigma0Squared(self._p, self._Rmod, adjuster) self._act = Sigma0SquaredAction(self._Sigma0Squared, self, act_on_left=act_on_left) self.register_action(self._act) self._populate_coercion_lists_() ## Initialise dictionaries of indices to translate between pairs and index for moments self._index = dict() self._ij = [] m = 0 ## Populate dictionary/array giving index of the basis element corr. to tuple (i,j), 0 <= i,j <= depth = n ## These things are ordered by degree of y, then degree of x: [1, x, x^2, ..., y, xy, ... ] for j in range(depth): for i in range(depth): self._ij.append((i, j)) self._index[(i, j)] = m m += 1 self._dimension = m ## Number of moments we store ## Power series ring Zp[[x,y]]. We have to work with monomials up to x^depth * y^depth, so need prec = 2*depth self._PowerSeries_x = PowerSeriesRing(self._Rmod, default_prec=self._depth, names='x') self._PowerSeries_x_ZZ = PowerSeriesRing(ZZ, default_prec=self._depth, names='x') self._PowerSeries = PowerSeriesRing(self._PowerSeries_x, default_prec=self._depth, names='y') self._PowerSeries_ZZ = PowerSeriesRing(self._PowerSeries_x_ZZ, default_prec=self._depth, names='y')
def create_key(self, k, p=None, prec_cap=None, base=None, \ character=None, adjuster=None, act_on_left=False, \ dettwist=None): k = ZZ(k) if base is None: if p is None: raise ValueError("Must specify a prime or a base ring.") if prec_cap is None: base = ZpCA(p) else: base = ZpCA(p, prec_cap) if prec_cap is None: prec_cap = base.precision_cap() elif prec_cap > base.precision_cap(): raise ValueError("Insufficient precision in base ring (%s < %s)."%(base.precision_cap(), prec_cap)) if p is None: p = base.prime() elif p != base.prime(): raise ValueError("Prime p(=%s) must equal the prime of the base ring(=%s)"%(p, base.prime())) if adjuster is None: adjuster = _default_adjuster() if dettwist is not None: dettwist = ZZ(dettwist) if dettwist == 0: dettwist = None return (k, p, prec_cap, base, character, adjuster, act_on_left, dettwist)
def __init__(self, k, p, prec_cap, base=None, character=None): if base is None: base = ZpCA(p,prec_cap) else: assert (isinstance(base, pAdicGeneric) and base.prime() == p) or (p.is_prime() and (base is ZZ or base is QQ)) from dist import Dist_vector, WeightKAction_vector, Dist_long, WeightKAction_long from sage.rings.padics.pow_computer import PowComputer_long # should eventually be the PowComputer on ZpCA once that uses longs. p = ZZ(p) # if 7*p** self._element_constructor_ = Dist_vector Parent.__init__(self, base) self._k = k self._p = ZZ(p) self._prec_cap = prec_cap self._approx_modules = {} # indexed by precision act = WeightKAction_vector(self, character) self._act = act self._populate_coercion_lists_(action_list=[act])
def create_key(self, k, p=None, prec_cap=None, base=None, symk=None, character=None, tuplegen=None, act_on_left=False): """ INPUT: - `k` -- nonnegative integer - `p` -- prime number or None - ``prec_cap`` -- positive integer or None - ``base`` -- ring or None - ``symk`` -- bool or None - ``character`` -- a dirichlet character or None - ``tuplegen`` -- None or callable that turns 2x2 matrices into a 4-tuple - ``act_on_left`` -- bool (default: False) EXAMPLES:: sage: from sage.modular.pollack_stevens.distributions import Distributions, Symk sage: Distributions(20, 3, 10) # indirect doctest Space of 3-adic distributions with k=20 action and precision cap 10 """ k = ZZ(k) if tuplegen is None: tuplegen = _default_tuplegen() if p is None: try: p = base.prime() except AttributeError: raise ValueError("You must specify a prime") else: p = ZZ(p) if base is None: if prec_cap is None: base = ZpCA(p) else: base = ZpCA(p, prec_cap) if prec_cap is None: try: prec_cap = base.precision_cap() except AttributeError: raise ValueError("You must specify a base or precision cap") return (k, p, prec_cap, base, character, tuplegen, act_on_left, symk)
def factor(self): # This will eventually be improved. if self == 0: raise ValueError, "Factorization of the zero polynomial not defined" from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.padics.factory import ZpCA base = self.base_ring() #print self.list() m = min([x.precision_absolute() for x in self.list()]) #print m R = ZpCA(base.prime(), prec = m) S = PolynomialRing(R, self.parent().variable_name()) F = S(self).factor() return Factorization([(self.parent()(a), b) for (a, b) in F], base(F.unit()))
def __init__(self, p, base_ring=None, adjuster=None): ## This is a parent in the category of monoids; initialise children Parent.__init__(self, category=Monoids()) self.Element = Sigma0SquaredElement ## base data initialisation self._R = ZZ self._p = p if base_ring is None: base_ring = ZpCA(p, 20) ## create Zp self._Rmod = base_ring ## underlying Sigma_0(p) self._Sigma0 = Sigma0(self._p, base_ring=base_ring, adjuster=adjuster) self._populate_coercion_lists_()
def change_precision(self, new_prec): """ Returns a FamiliesOfOMS coefficient module with same input data as self, but with precision cap ``new_prec`` """ #print new_prec if new_prec == self._prec_cap: return self base_coeffs = self.base_ring().base_ring() if new_prec[0] > base_coeffs.precision_cap(): #THERE'S NO WAY TO EXTEND PRECISION ON BASE RING!!! This is a crappy hack: if base_coeffs.is_field(): base_coeffs = Qp(self.prime(), new_prec[0]) else: base_coeffs = ZpCA(self.prime(), new_prec[0]) return FamiliesOfOverconvergentDistributions(self._k, prec_cap = new_prec, base_coeffs=base_coeffs, character=self._character, adjuster=self._adjuster, act_on_left=self.action().is_left(), dettwist=self._dettwist, variable_name = self.base_ring().variable_name())
def find_Apow_and_ord_two_stage(A, E, p, prec, nu=0): f_degree = A.change_ring(GF(p)).charpoly().splitting_field(names='a').degree() r = (p**f_degree - 1) * p**prec A = A.change_ring(ZpCA(p,prec)) Apow = take_power(A, r - 1 -nu) Ar = multiply_and_reduce(Apow, A) Ar = my_ech_form(Ar,p) # In place! ord_basis = [] for o in Ar.rows(): if o.is_zero(): break ord_basis.append(o) E = try_lift(E) ord_basis_qexp = try_lift(Matrix(ord_basis)).change_ring(QQ) * E return ord_basis_qexp, Apow
def __init__(self, p, depth): Module.__init__(self, base=ZZ) self._R = ZZ self._p = p self._Rmod = ZpCA(p, depth - 1) self._depth = depth self._pN = self._p**(depth - 1) self._PowerSeries = PowerSeriesRing(self._Rmod, default_prec=self._depth, name='z') self._cache_powers = dict() self._unset_coercions_used() self._Sigma0 = Sigma0(self._p, base_ring=self._Rmod, adjuster=our_adjuster()) self.register_action(Sigma0Action(self._Sigma0, self)) self._populate_coercion_lists_()
def find_Apow_and_ord_three_stage(A, E, p, prec, nu=0): R = ZpCA(p,prec) s0inv = QQ(2) first_power = QQ(prec * s0inv).ceil() Upa = take_power(A, first_power) ord_basis_qexp = [] Apow_echelon = Upa.parent()(Upa) Apow_echelon = my_ech_form(try_lift(Apow_echelon).change_ring(R), p) # In place! ord_basis_0 = multiply_and_reduce(Apow_echelon,E) for qexp in ord_basis_0.rows(): if qexp != 0: #min(o.valuation(p) for o in qexp) < prec: # != 0: ord_basis_qexp.append(qexp) ord_basis = try_lift(Matrix(ord_basis_qexp)).change_ring(R) Up_on_ord = hecke_matrix_on_ord(p, ord_basis, None, level = p).change_ring(R) f_degree = try_lift(Up_on_ord).change_ring(GF(p)).charpoly().splitting_field(names='a').degree() r = (p**f_degree - 1) * p**prec Upb_on_ord = take_power(Up_on_ord, r - first_power - 1 - nu) return ord_basis, Upa, Upb_on_ord
def change_precision(self, new_prec): """ Returns an OMS coefficient module with same input data as self, but with precision cap ``new_prec`` """ if new_prec == self._prec_cap: return self base = self.base_ring() if new_prec > base.precision_cap(): #THERE'S NO WAY TO EXTEND PRECISION ON BASE RING!!! This is a crappy hack: if self.base_ring().is_field(): base = Qp(self.prime(), new_prec) else: base = ZpCA(self.prime(), new_prec) return OverconvergentDistributions(self._k, prec_cap=new_prec, base=base, character=self._character, adjuster=self._adjuster, act_on_left=self.action().is_left(), dettwist=self._dettwist)
def test_correctness_and_precision_of_solve_diff_eqn(number=20, verbosity=1): """ ``number`` is how many different random distributions to check. Currently, avoids the prime 2. """ from sage.misc.prandom import randint from sage.rings.arith import random_prime from sage.rings.padics.factory import ZpCA from sage.modular.pollack_stevens.coeffmod_OMS_space import OverconvergentDistributions from sage.structure.sage_object import dumps errors = [] munus = [] for i in range(number): Mspace = randint(1, 20) #Moments of space M = randint(max(0, Mspace - 5), Mspace) p = random_prime(13, lbound=3) k = randint(0, 6) Rprec = Mspace + randint(0, 5) R = ZpCA(p, Rprec) D = OverconvergentDistributions(k, base=R, prec_cap=Mspace) S0 = D.action().actor() Delta_mat = S0([1,1,0,1]) mu = D.random_element(M) mu_save = dumps(mu)#[deepcopy(mu.ordp), deepcopy(mu._moments)] if verbosity > 0: print "\nTest #{0} data (Mspace, M, p, k, Rprec) =".format(i+1), (Mspace, M, p, k, Rprec) print "mu =", mu nu = mu * Delta_mat - mu nu_save = [deepcopy(nu.ordp), deepcopy(nu._moments)] mu2 = nu.solve_diff_eqn() nu_abs_prec = nu.precision_absolute() expected = nu_abs_prec - nu_abs_prec.exact_log(p) - 1 if M != 1: try: agree = (mu - mu2).is_zero(expected) except PrecisionError: print (Mspace, M, p, k, Rprec), mu_save._repr_(), nu_save assert False else: agree = mu2.is_zero(expected) if verbosity > 1: print " Just so you know:" print " mured =", mu.reduce_precision_absolute(expected) print " mu2 =", mu2 print " nu = ", nu if not agree: errors.append((i+1, 1)) munus.append((mu_save, nu_save, mu2, (Mspace, M, p, k, Rprec))) if verbosity > 0: print " Test finding mu from mu|Delta accurate: %s"%(agree) print " nu_abs_prec soln_abs_prec_expected actual agree" mu2_abs_prec = mu2.precision_absolute() agree = (expected == mu2_abs_prec) if verbosity > 0: print " %s %s %s %s"%(nu_abs_prec, expected, mu2_abs_prec, agree) if not agree: errors.append((i+1, 2)) munus.append((mu_save, nu_save, mu2, (Mspace, M, p, k, Rprec))) if mu.precision_relative() > 0: mu._moments[0] = R(0, mu.precision_relative()) mu_save = [deepcopy(mu.ordp), deepcopy(mu._moments)] if verbosity > 0: print " mu modified =", mu nu = mu.solve_diff_eqn() mu_abs_prec = mu.precision_absolute() expected = mu_abs_prec - mu_abs_prec.exact_log(p) - 1 nud = nu * Delta_mat - nu nu_save = [deepcopy(nu.ordp), deepcopy(nu._moments)] agree = (nud - mu).is_zero(expected) if verbosity > 1: print " Just so you know:" print " mu =", mu print " mured =", mu.reduce_precision_absolute(expected) print " nud =", nud if not agree: errors.append((i+1, 3)) munus.append((mu_save, nu_save, (Mspace, M, p, k, Rprec))) if verbosity > 0: print " Test finding nu with nu|Delta == mu: %s"%(agree) print " mu_abs_prec soln_abs_prec_expected actual agree" nu_abs_prec = nu.precision_absolute() agree = (expected == nu_abs_prec) if verbosity > 0: print " %s %s %s %s"%(mu_abs_prec, expected, nu_abs_prec, agree) if not agree: errors.append((i+1, 4)) munus.append((mu_save, nu_save, (Mspace, M, p, k, Rprec))) if len(errors) == 0: if verbosity > 0: print "\nTest passed with no errors." return if verbosity > 0: print "\nTest failed with errors: %s\n"%(errors) return errors, munus