Exemple #1
0
    def coleman(self,t1,t2,E=None,method='moments',mult=False,delta=-1,level=0):
        r"""
        If ``self`` is a `p`-adic automorphic form that corresponds to a rigid modular form,
        then this computes the coleman integral of this form between two points on
        the boundary `\PP^1(\QQ_p)` of the `p`-adic upper half plane.

        INPUT:

         - ``t1``, ``t2`` - elements of `\PP^1(\QQ_p)` (the endpoints of integration)

         - ``E`` - (Default: None). If specified, will not compute the covering adapted
            to ``t1`` and ``t2`` and instead use the given one. In that case, ``E``
            should be a list of matrices corresponding to edges describing the open
            balls to be considered.

         - ``method`` - string (Default: 'moments'). Tells which algorithm to use 
           (alternative is 'riemann_sum', which is unsuitable for computations 
           requiring high precision)

         - ``mult`` - boolean (Default: False). Whether to use the multiplicative version.

         - ``delta`` - integer (Default: -1)

         - ``level`` - integer (Default: 0)

        OUTPUT:

          The result of the coleman integral

        EXAMPLES:

        This example illustrates ...

        ::

        TESTS:

        ::
            sage: p = 7
            sage: lev = 2
            sage: prec = 20
            sage: X = BTQuotient(p,lev, use_magma = True) # optional - magma
            sage: k = 2 # optional - magma
            sage: M = HarmonicCocycles(X,k,prec) # optional - magma
            sage: B = M.basis() # optional - magma
            sage: f = 3*B[0] # optional - magma
            sage: MM = pAutomorphicForms(X,k,prec,overconvergent=True) # optional - magma
            sage: D = -11 # optional - magma
            sage: X.is_admissible(D) # optional - magma
            True
            sage: K.<a> = QuadraticField(D) # optional - magma
            sage: CM = X.get_CM_points(D,prec=prec) # optional - magma
            sage: Kp = CM[0].parent() # optional - magma
            sage: P=CM[0] # optional - magma
            sage: Q=P.trace()-P # optional - magma
            sage: F=MM.lift(f, verbose = False) # long time optional - magma
            sage: J0=F.coleman(P,Q,mult=True) # long time optional - magma
            sage: E=EllipticCurve([1,0,1,4,-6]) # optional - magma
            sage: T=E.tate_curve(p) # optional - magma
            sage: xx,yy=getcoords(T,J0,prec) # long time optional -magma
            sage: P = E.base_extend(K).lift_x(algdep(xx,1).roots(QQ)[0][0]); P # long time optional - magma
            (7/11 : 58/121*a - 9/11 : 1)

            sage: p = 13 # optional - magma
            sage: lev = 2 # optional - magma
            sage: prec = 20 # optional - magma
            sage: Y = BTQuotient(p,lev, use_magma = True) # optional - magma
            sage: k = 2 # optional - magma
            sage: M=HarmonicCocycles(Y,k,prec) # optional - magma
            sage: B=M.basis() # optional - magma

            sage: f = B[1] # optional - magma
            sage: g = -4*B[0]+3*B[1] # optional - magma
            sage: MM = pAutomorphicForms(Y,k,prec,overconvergent=True) # optional - magma
            sage: D = -11 # optional - magma
            sage: Y.is_admissible(D) # optional - magma
            True
            sage: K.<a> = QuadraticField(D) # optional - magma
            sage: CM = Y.get_CM_points(D,prec=prec) # optional - magma
            sage: Kp = parent(CM[0]) # optional - magma
            sage: P = CM[0] # optional - magma
            sage: Q = P.trace()-P # optional - magma
            sage: F = MM.lift(f, verbose = False) # long time optional - magma
            sage: J11 = F.coleman(P,Q,mult = True) # long time optional - magma
            sage: E = EllipticCurve('26a2') # optional - magma
            sage: T = E.tate_curve(p) # optional - magma
            sage: xx,yy = getcoords(T,J11,prec) # long time optional - magma
            sage: HP = E.base_extend(K).lift_x(algdep(xx,1).roots(QQ)[0][0]); HP # long time optional - magma
            (-137/11 : 2/121*a + 63/11 : 1)

        AUTHORS:

        - Cameron Franc (2012-02-20)
        - Marc Masdeu (2012-02-20)
        """
        if(mult and delta>=0):
            raise NotImplementedError, "Need to figure out how to implement the multiplicative part."
        p=self._parent._X._p
        K=t1.parent()
        R=PolynomialRing(K,'x')
        x=R.gen()
        R1=LaurentSeriesRing(K,'r1')
        r1=R1.gen()
        if(E is None):
            E=self._parent._X._BT.find_covering(t1,t2)
            # print 'Got %s open balls.'%len(E)
        value=0
        ii=0
        value_exp=K(1)
        if(method=='riemann_sum'):
            R1.set_default_prec(self._parent._U.weight()+1)
            for e in E:
                ii+=1
                b=e[0,1]
                d=e[1,1]
                y=(b-d*t1)/(b-d*t2)
                poly=R1(y.log()) #R1(our_log(y))
                c_e=self.evaluate(e)
                new=c_e.evaluate(poly)
                value+=new
                if mult:
                    value_exp *= K.teichmuller(y)**Integer(c_e[0].rational_reconstruction())

        elif(method=='moments'):
            R1.set_default_prec(self._parent._U.dimension())
            for e in E:
                ii+=1
                f=(x-t1)/(x-t2)
                a,b,c,d=e.list()
                y0=f(R1([b,a])/R1([d,c])) #f( (ax+b)/(cx+d) )
                y0=p**(-y0(0).valuation())*y0
                mu=K.teichmuller(y0(0))
                y=y0/mu-1
                poly=R1(0)
                ypow=y
                for jj in range(1,R1.default_prec()+10):
                    poly+=(-1)**(jj+1)*ypow/jj
                    ypow*=y
                if(delta>=0):
                    poly*=((r1-t1)**delta*(r1-t2)**(self._parent._n-delta))
                c_e=self.evaluate(e)
                new=c_e.evaluate(poly)
                value+=new
                if mult:
                    value_exp *= K.teichmuller((b-d*t1)/(b-d*t2))**Integer(c_e[0].rational_reconstruction())

        else:
            print 'The available methods are either "moments" or "riemann_sum". The latter is only provided for consistency check, and should not be used in practice.'
            return False
        if mult:
            return value_exp * value.exp()
        return value