@@ -2661,3 +2661,128 @@ cdef class pAdicGenericElement(LocalGenericElement):
2661
2661
2662
2662
"""
2663
2663
raise NotImplementedError
2664
+
2665
+ def polylog(self, n):
2666
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
2667
+ from sage.rings.power_series_ring import PowerSeriesRing
2668
+ from sage.rings.padics.factory import Qp
2669
+ from sage.misc.all import verbose
2670
+ from sage.functions.log import log
2671
+ from sage.functions.other import ceil
2672
+
2673
+ def _polylog_c(n,p):
2674
+ return p/(p-1) - (n-1)/log(p) + (n-1)*log(n*(p-1)/log(p),p) + log(2*p*(p-1)*n/log(p), p)
2675
+
2676
+ def _compute_g(p, n, prec, terms):
2677
+ # Compute the sequence of power series g
2678
+ R = PowerSeriesRing(Qp(p, ceil(prec)), default_prec=terms, names='v')
2679
+ v = R.gen()
2680
+ g = (n+1)*[0]
2681
+ g[0] = v-1 - ((v-1)**p)/(v**p-(v-1)**p)
2682
+ for i in range(n):
2683
+ g[i+1] = -(g[i]/(v-v**2)).integral()
2684
+ return [x.truncate(terms) for x in g]
2685
+
2686
+ def _findprec(c_1,c_2,c_3,p):
2687
+ k = ceil(c_1/c_2)
2688
+ while True:
2689
+ if c_1*k - c_2*k.log(p) > c_3:
2690
+ return k
2691
+ k += 1
2692
+
2693
+ def _Li_n_res_1(p, n, z0, prec):
2694
+ """
2695
+ compute Li_n for z0 = 1 mod p
2696
+ """
2697
+ if z0 == 1:
2698
+ raise ValueError('z0 cannot be 1!')
2699
+ elif p == 2:
2700
+ raise ValueError('p cannot be 2!')
2701
+ else:
2702
+ hsl = _findprec((z0-1).valuation(p), n, prec, p) # TODO increase if p = 2
2703
+ K = Qp(p,ceil(prec + n*log(hsl-1,p)))
2704
+ gsl = max([_findprec(1/(p-1), 1, prec - m + _polylog_c(m,p)+ K(1-2**(m-1)).valuation() + (n-m)*(hsl-1).log(p), p) for m in range(2,n+1)])
2705
+ g = _compute_g(p, n, prec, gsl)
2706
+ S = PowerSeriesRing(K, default_prec=hsl,names='t')
2707
+ t = S.gen()
2708
+ G = [((1+t).log())**i/Integer(i).factorial() for i in range(n+4)]
2709
+
2710
+ H = (n+1)*[0]
2711
+ H[2] = sum((-1)**i*t**i/(i+1) for i in range(hsl+1)).integral()
2712
+ for i in range(2,n):
2713
+ H0 = 0
2714
+ if (i + 1) % 2 == 1:
2715
+ H0 = 2**i*p**(i+1)*g[i+1](1/2)/((1-2**i)*(p**(i+1) - 1))
2716
+ H[i+1] = (H[i]/(1+t) + G[i]/t).integral() + H0
2717
+
2718
+ return Qp(p,prec)(H[n](K(z0-1)) - (K(z0).log(0))**(n-1)*K(1-z0).log(0)/Integer(n-1).factorial())
2719
+
2720
+ def _Li_n(p = 7, n = 3, z0 = 1/2, prec = 20):
2721
+ """
2722
+ Return Li_n(z0) , the p- adic polylogarithm of ``z0`` to precision prec.
2723
+
2724
+ z0 not infinity or 1 mod p
2725
+
2726
+ INPUT:
2727
+
2728
+ - ``p`` -- (default: 7 ) a positive prime integer
2729
+ - ``n`` -- (default: 2 ) a positive integer
2730
+ - prec -- (default: 15 ) a positive integer
2731
+
2732
+ OUTPUT:
2733
+
2734
+ - Li_n(z0)
2735
+
2736
+ EXAMPLES:
2737
+ ::
2738
+
2739
+ sage: Li_n(13 , 6 , - 1 ) == 0
2740
+ True
2741
+
2742
+ """
2743
+ K = Qp(p,prec)
2744
+ res = 'infty' # Assume residue disk around oo
2745
+ if K(z0).valuation() >= 0:
2746
+ res = K(z0).residue()
2747
+
2748
+ # Which residue disk are we in
2749
+ if res == 0:
2750
+ verbose("residue 0, using series. %d %s "%(n,str(z0)), level=2)
2751
+ return sum(K(z0)**k/k**n for k in range(1,p*prec))
2752
+ if res == 1 and K(z0) == 1:
2753
+ raise ValueError
2754
+ # Residue disk around 1
2755
+ if res == 1 and K(z0) != 1:
2756
+ verbose("residue 1, using Li_n_res_1. %d %s "%(n,str(z0)), level=2)
2757
+ return _Li_n_res_1(p, n, z0, prec)
2758
+ if res == 'infty':
2759
+ verbose("residue oo, using functional equation for reciprocal. %d %s "%(n,str(z0)), level=2)
2760
+ return (-1)**(n+1)*_Li_n(p,n,1/z0,prec)-(K(z0).log(0)**n)/K(n.factorial())
2761
+
2762
+ P = PolynomialRing(K, 'x')
2763
+ x = P.gen()
2764
+ f = x**(p-1)-1
2765
+ roots = f.roots(multiplicities=False) # TODO use K.zeta here?
2766
+ for x in roots:
2767
+ if (z0 - x).valuation() > 0:
2768
+ zeta = x
2769
+
2770
+ # Set up precision bounds
2771
+ tsl = _findprec((z0-zeta).valuation(), n, prec, p)
2772
+ gsl = max([_findprec(1/(p-1), 1, prec - m + _polylog_c(m,p) + (n-m)*(tsl-1).log(p), p) for m in range(1,n+1)])
2773
+
2774
+ gtr = _compute_g(p, n, prec + n*(tsl -1).log(p) + n*(gsl-1).log(p), gsl)
2775
+
2776
+ # Residue disk around zeta
2777
+ verbose("general case. %d %s "%(n,str(z0)), level=2)
2778
+ Li_i_zeta = [0] + [p**i/(p**i-1)*gtr[i](1/(1-zeta)) for i in range(1,n+1)]
2779
+
2780
+ T = PowerSeriesRing(K, default_prec=tsl, names='t')
2781
+ t = T.gen()
2782
+ F = (n+1)*[0]
2783
+ F[0] = (zeta+t)/(1-zeta-t)
2784
+ for i in range(n):
2785
+ F[i+1] = Li_i_zeta[i+1] + (F[i]/(zeta+t)).integral()
2786
+ return Qp(p, prec)(F[n](z0-zeta))
2787
+
2788
+ return _Li_n(self.parent().prime(), n, self, self.precision_absolute())
0 commit comments