def _iter_positive_forms_with_content_and_discriminant(self) :
        if self.__disc is infinity :
            raise ValueError, "infinity is not a true filter index"
        
        if self.__reduced :
            for (l, (u,x)) in enumerate(self.__p1list) :
                if u == 0 :
                    for a in xrange(self.__level, isqrt(self.__disc // 4) + 1, self.__level) :
                        frpa = 4 * a
                        for b in xrange(a+1) :
                            g = gcd(a // self.__level,b)
                            bsq = b**2

                            for c in xrange(a, (b**2 + (self.__disc - 1))//(4*a) + 1) :
                                yield (((a,b,c), l), gcd(g,c), frpa*c - bsq)
                else :
                    for a in xrange(1, isqrt(self.__disc // 3) + 1) :
                        frpa = 4 * a
                        for b in xrange(a+1) :
                            g = gcd(a, b)
                            bsq = b**2
                                                        
                            ## We need x**2 * a + x * b + c % N == 0
                            h = (-((x**2 + 1) * a + x * b)) % self.__level
                            for c in xrange( a + h,
                                             (b**2 + (self.__disc - 1))//(4*a) + 1, self.__level ) :
                                yield (((a,b,c), l), gcd(g,(x**2 * a + x * b + c) // self.__level), frpa*c - bsq)
        #! if self.__reduced
        else :
            raise NotImplementedError
        
        raise StopIteration
    def iter_positive_forms_with_content(self) :
        if self.__disc is infinity :
            raise ValueError, "infinity is not a true filter index"
        
        
        if self.__reduced :        
            for a in xrange(1,isqrt(self.__disc // 3) + 1) :
                for b in xrange(a+1) :
                    g = gcd(a, b)
                    for c in xrange(a, (b**2 + (self.__disc - 1))//(4*a) + 1) :
                        yield (a,b,c), gcd(g,c)
        else :
            maxtrace = floor(5*self.__disc / 15 + sqrt(self.__disc)/2)
            for a in xrange(1, maxtrace + 1) :
                for c in xrange(1, maxtrace - a + 1) :
                    g = gcd(a,c)
                    
                    Bu = isqrt(4*a*c - 1)

                    di = 4*a*c - self.__disc
                    if di >= 0 :
                        Bl = isqrt(di) + 1 
                    else :
                        Bl = 0
                    
                    for b in xrange(-Bu, -Bl + 1) :
                        yield (a,b,c), gcd(g,b)
                    for b in xrange(Bl, Bu + 1) :
                        yield (a,b,c), gcd(g,b)
        #! if self.__reduced

        raise StopIteration
    def _calc_iter_reduced_sub4(self) :
        try :
            return self.__iter_reduced_sub4
        except AttributeError :
            pass
        
        sub3 = self._calc_iter_reduced_sub3()
        
        sub4 = list()
        for (a0,a1,b01,sub3s) in sub3 :
            sub4s = list()
            for (a2, b02, b12) in sub3s :
                sub4ss = list()
                for a3 in xrange(2, 2 * self.index() + 1, 2) :
                    # obstruction for t[0,3]
                    B1 = isqrt(a0 * a3 - 1)
                
                    for b03 in xrange(-B1, B1 + 1) :
                        # obstruction for t[1,3]
                        B3 = isqrt(a1 * a3 - 1)

                        for b13 in xrange(-B3, B3 + 1) :
                            # obstruction for the minor [0,1,3] of t
                            if a0*a1*a3 - a0*b12**2 + 2*b01*b13*b03 - b01**2*a3 - a1*b03**2 <= 0 :
                                continue
                            
                            # obstruction for t[2,3]
                            B3 = isqrt(a2 * a3 - 1)
                            
                            for b23 in xrange(-B3, B3 + 1) :
                                # obstruction for the minor [0,2,3] of t
                                if a0*a2*a3 - a0*b23**2 + 2*b02*b23*b03 - b02**2*a3 - a2*b03**2 <= 0 :
                                    continue
                                
                                # obstruction for the minor [1,2,3] of t
                                if a1*a2*a3 - a1*b23**2 + 2*b12*b23*b13 - b12**2*a3 - a2*b13**2 <= 0 :
                                    continue

                                t = matrix(ZZ, 4, [a0, b01, b02, b03, b01, a1, b12, b13, b02, b12, a2, b23, b03, b13, b23, a3], check = False)
                                if t.det() <= 0 :
                                    continue
                                
                                u = t.LLL_gram()
                                if u.transpose() * t * u != t :
                                    continue
                                                                   
                                sub4ss.append((a3, b03, b13, b23))
                sub4s.append((a2, b02, b12, sub4ss))
            sub4.append((a0, a1, b01, sub4s))
        
        self.__iter_reduced_sub4 = sub4

        return sub4
 def decompositions(self, s) :
     (a, b, c) = s
     
     for a1 in xrange(a + 1) :
         a2 = a - a1
         for c1 in xrange(c + 1) :
             c2 = c - c1
             
             B1 = isqrt(4*a1*c1)
             B2 = isqrt(4*a2*c2)
             for b1 in xrange(max(-B1, b - B2), min(B1 + 1, b + B2 + 1)) :
                 yield ((a1, b1, c1), (a2,b - b1, c2))
     
     raise StopIteration
 def decompositions(self, s) :
     (n, r) = s
     
     fm = 4 * self.__m
     if self.__weak_forms :
         yield ((0,0), (n,r)) 
         yield ((n,r), (0,0))
         
         msq = self.__m**2
         for n1 in xrange(1, n) :
             n2 = n - n1
             for r1 in xrange( max(r - isqrt(fm * n2 + msq),
                                   isqrt(fm * n1 + msq - 1) + 1),
                               min( r + isqrt(fm * n2 + msq) + 1,
                                    isqrt(fm * n1 + msq) + 1 ) ) :
                 yield ((n1, r1), (n2, r - r1))
     else :
         yield ((0,0), (n,r)) 
         yield ((n,r), (0,0))
         
         for n1 in xrange(1, n) :
             n2 = n - n1
             ##r = r1 + r2
             ##r1**2 <= 4 n1 m
             ## (r - r1)**2 <= 4 n2 m
             ## r1**2 - 2*r1*r + r**2 - 4 m n2 <= 0
             ## r1 <-> r \pm \sqrt{r**2 - r**2 + 4 m n2}
             for r1 in xrange( max(r - isqrt(fm * n2),
                                   isqrt(fm * n1 - 1) + 1),
                               min( r + isqrt(fm * n2) + 1,
                                    isqrt(fm * n1) + 1 ) ) :
                 yield ((n1, r1), (n2, r - r1))
             
     raise StopIteration
Example #6
0
    def duke_imamoglu_lift(self, f, f_k, precision, half_integral_weight = False) :
        """
        INPUT:
        
        - ``half_integral_weight``   -- If ``False`` we assume that `f` is the Fourier expansion of a
                                        Jacobi form. Otherwise we assume it is the Fourier expansion
                                        of a half integral weight elliptic modular form.
        """
        
        if half_integral_weight :
            coeff_index = lambda d : d
        else :
            coeff_index = lambda d : ((d + (-d % 4)) // 4, (-d) % 4)
        
        coeffs = dict()
        
        for t in precision.iter_positive_forms() :
            dt = (-1)**(precision.genus() // 2) * t.det()
            d = fundamental_discriminant(dt)
            eps = Integer(isqrt(dt / d))
    
            coeffs[t] = 0 
            for a in eps.divisors() :
                d_a = abs(d * (eps // a)**2)
                 
                coeffs[t] = coeffs[t] + a**(f_k - 1) * self._kohnen_phi(a, t) \
                                        * f[coeff_index(d_a)]

        return coeffs
Example #7
0
 def _kohnen_phi(self, a, t) :
     ## We use a modified power of a, namely for each prime factor p of a
     ## we use p**floor(v_p(a)/2). This is compensated for in the routine
     ## of \rho
     a_modif = 1
     for (p,e) in a.factor() :
         a_modif = a_modif * p**(e // 2)
     
     res = 0
     for dsq in filter(lambda d: d.is_square(), a.divisors()) :
         d = isqrt(dsq)
         
         for g_diag in itertools.ifilter( lambda diag: prod(diag) == d,
                               itertools.product(*[d.divisors() for _ in xrange(t.nrows())]) ) :
             for subents in itertools.product(*[xrange(r) for (j,r) in enumerate(g_diag) for _ in xrange(j)]) :
                 columns = [subents[(j * (j - 1)) // 2:(j * (j + 1)) // 2] for j in xrange(t.nrows())]
                 g = diagonal_matrix(list(g_diag))
                 for j in xrange(t.nrows()) :
                     for i in xrange(j) :
                         g[i,j] = columns[j][i]
                      
                 ginv = g.inverse()   
                 tg = ginv.transpose() * t * ginv
                 try :
                     tg= matrix(ZZ, tg)
                 except :
                     continue
                 if any(tg[i,i] % 2 == 1 for i in xrange(tg.nrows())) :
                     continue
                 
                 tg.set_immutable()
                     
                 res = res + self._kohnen_rho(tg, a // dsq)
     
     return a_modif * res
    def decompositions(self, t) :
        for diag in itertools.product(*[xrange(t[i,i] + 1) for i in xrange(self.__n)]) :
            for subents in  itertools.product( *[ xrange(-2 * isqrt(diag[i] * diag[j]), 2 * isqrt(diag[i] * diag[j]) + 1)
                                                  for i in xrange(self.__n - 1) 
                                                  for j in xrange(i + 1, self.__n) ] ) :
                t1 = matrix(ZZ, [[ 2 * diag[i]
                                   if i == j else
                                      (subents[self.__n * i - (i * (i + 1)) // 2 + j - i - 1]
                                       if i < j else
                                       subents[self.__n * j - (j * (j + 1)) // 2 + i - j - 1])
                                  for i in xrange(self.__n) ]
                                 for j in xrange(self.__n) ] )
 
                if self._check_definiteness(t1) == -1 :
                    continue
 
                t2 = t - t1
                if self._check_definiteness(t2) == -1 :
                    continue
                
                t1.set_immutable()
                t2.set_immutable()
                
                yield (t1, t2)

        raise StopIteration
    def _by_taylor_expansion_m1(self, f_divs, k, is_integral=False) :
        r"""
        This provides special, faster code in the Jacobi index `1` case.
        """
        if is_integral :
            PS = self.integral_power_series_ring()
        else :
            PS = self.power_series_ring()
            
        qexp_prec = self._qexp_precision()
        
        
        fderiv = f_divs[(0,0)].derivative().shift(1)
        f = f_divs[(0,0)] * Integer(k/2)
        gfderiv = f_divs[(1,0)] - fderiv
        
        ab_prec = isqrt(qexp_prec + 1)
        a1dict = dict(); a0dict = dict()
        b1dict = dict(); b0dict = dict()
    
        for t in xrange(1, ab_prec + 1) :
            tmp = t**2
            a1dict[tmp] = -8*tmp
            b1dict[tmp] = -2
        
            tmp += t
            a0dict[tmp] = 8*tmp + 2
            b0dict[tmp] = 2
        b1dict[0] = -1
        a0dict[0] = 2; b0dict[0] = 2 
        
        a1 = PS(a1dict); b1 = PS(b1dict)
        a0 = PS(a0dict); b0 = PS(b0dict)

        Ifg0 = (self._eta_factor() * (f*a0 + gfderiv*b0)).list()
        Ifg1 = (self._eta_factor() * (f*a1 + gfderiv*b1)).list()

        if len(Ifg0) < qexp_prec :
            Ifg0 += [0]*(qexp_prec - len(Ifg0))
        if len(Ifg1) < qexp_prec :
            Ifg1 += [0]*(qexp_prec - len(Ifg1))
                    
        Cphi = dict([(0,0)])
        for i in xrange(qexp_prec) :
            Cphi[-4*i] = Ifg0[i]
            Cphi[1-4*i] = Ifg1[i]

        del Ifg0[:], Ifg1[:]

        phi_coeffs = dict()
        m = self.__precision.jacobi_index()
        for r in xrange(2 * self.__precision.jacobi_index()) :
            for n in xrange(qexp_prec) :
                k = 4 * m * n - r**2
                if k >= 0 :
                    phi_coeffs[(n, r)] = Cphi[-k]
                               
        return phi_coeffs
    def __iter__(self) :
        if self.__bound is infinity :
            raise ValueError, "infinity is not a true filter index"

        if self.__reduced :
            ##TODO: This is really primitive. We barely reduce arbitrary forms.
            for diag in itertools.product(*[xrange(self.__bound) for _ in xrange(self.__n)]) :
                for subents in  itertools.product( *[ xrange(-2 * isqrt(diag[i] * diag[j]), 2 * isqrt(diag[i] * diag[j]) + 1)
                                                      for i in xrange(self.__n - 1) 
                                                      for j in xrange(i + 1, self.__n) ] ) :
                    t = matrix(ZZ, [[ 2 * diag[i]
                                      if i == j else
                                      (subents[self.__n * i - (i * (i + 1)) // 2 + j - i - 1]
                                       if i < j else
                                       subents[self.__n * j - (j * (j + 1)) // 2 + i - j - 1])
                                     for i in xrange(self.__n) ]
                                    for j in xrange(self.__n) ] )

                    t = self.__ambient.reduce(t)
                    if t is None : continue
                    t = t[0]
                    
                    t.set_immutable()
                    
                    yield t
        else :
            for diag in itertools.product(*[xrange(self.__bound) for _ in xrange(self.__n)]) :
                for subents in  itertools.product( *[ xrange(-2 * isqrt(diag[i] * diag[j]), 2 * isqrt(diag[i] * diag[j]) + 1)
                                                      for i in xrange(self.__n - 1) 
                                                      for j in xrange(i + 1, self.__n) ] ) :
                    t = matrix(ZZ, [[ 2 * diag[i]
                                      if i == j else
                                      (subents[self.__n * i - (i * (i + 1)) // 2 + j - i - 1]
                                       if i < j else
                                       subents[self.__n * j - (j * (j + 1)) // 2 + i - j - 1])
                                     for i in xrange(self.__n) ]
                                    for j in xrange(self.__n) ] )
                    if self._check_definiteness(t) == -1 :
                        continue
                    
                    t.set_immutable()
                    
                    yield t

        raise StopIteration
 def decompositions(self, s) :
     ((a, b, c), l) = s
     
     #                  r t r^tr = t_1 + t_2
     # \Rightleftarrow  t = r t_1 r^tr + r t_2 r^tr
     for a1 in xrange(a + 1) :
         a2 = a - a1
         for c1 in xrange(c + 1) :
             c2 = c - c1
             
             B1 = isqrt(4*a1*c1)
             B2 = isqrt(4*a2*c2)
             for b1 in xrange(max(-B1, b - B2), min(B1 + 1, b + B2 + 1)) :
                 h1 = apply_GL_to_form(self.__p1list[l], (a1, b1, c1))
                 h2 = apply_GL_to_form(self.__p1list[l], (a2, b - b1, c2))
                 if h1[2] % self.__level == 0 and h2[2] % self.__level == 0:
                     yield ((h1, 1), (h2,1))
     
     raise StopIteration
    def iter_indefinite_forms(self) :
        r"""
        Iterate over indices with non-positive discriminant.
        
        TESTS::
        
            sage: from psage.modform.jacobiforms.jacobiformd1nn_fourierexpansion import *
            sage: list(JacobiFormD1NNFilter(2, 2, reduced = False, weak_forms = True).iter_indefinite_forms())
            [(0, -1), (1, 3), (0, 0), (1, -3), (0, 1), (0, -2), (0, 2)]
            sage: list(JacobiFormD1NNFilter(3, 2, reduced = False, weak_forms = True).iter_indefinite_forms())
            [(0, -1), (1, 3), (2, -4), (0, 0), (2, 4), (1, -3), (0, 1), (0, -2), (0, 2)]
            sage: list(JacobiFormD1NNFilter(10, 2, reduced = True, weak_forms = True).iter_indefinite_forms())
            [(0, 0), (0, 1), (0, 2)]
            sage: list(JacobiFormD1NNFilter(10, 3, reduced = True, weak_forms = True).iter_indefinite_forms())
            [(0, 0), (0, 1), (0, 2), (0, 3)]
            sage: list(JacobiFormD1NNFilter(10, 10, reduced = True, weak_forms = True).iter_indefinite_forms())                                                  
            [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (1, 7), (1, 8), (1, 9), (1, 10), (2, 9), (2, 10)]
        """
        B = self.__bound
        m = self.__m
        fm = Integer(4 * self.__m)
        
        if self.__reduced :
            if self.__weak_forms :
                for n in xrange(0, min(self.__m // 4 + 1, self.__bound)) :
                    for r in xrange( isqrt(fm * n - 1) + 1 if n != 0 else 0, self.__m + 1 ) :
                        yield (n, r)
            else :
                for r in xrange(0, min(self.__m + 1,
                                       isqrt((self.__bound - 1) * fm) + 1) ) :
                    if fm.divides(r**2) :
                        yield (r**2 // fm, r)
        else :
            if self.__weak_forms :
                ## We first determine the reduced indices.
                for n in xrange(0, min(m // 4 + 1, B)) :
                    if n == 0 :
                        r_iteration = range(-m + 1, m + 1)
                    else :
                        r_iteration =   range( -m + 1, -isqrt(fm * n - 1) ) \
                                       + range( isqrt(fm * n - 1) + 1, m + 1 )
                    for r in  r_iteration :
                        for l in range( (- r - isqrt(r**2 - 4 * m * (n - (B - 1))) - 1) // (2 * m) + 1,
                                        (- r + isqrt(r**2 - 4 * m * (n - (B - 1)))) // (2 * m) + 1 ) :
                            if n + l * r + m * l**2 >= B :
                                print l, n, r
                            yield (n + l * r + m * l**2, r + 2 * m * l)
            else :
                if self.__bound > 0 :
                    yield (0,0)

                for n in xrange(1, self.__bound) :
                    if (fm * n).is_square() :
                        rt_fmm = isqrt(fm * n)
                        yield(n, rt_fmm)
                        yield(n, -rt_fmm)
        
        raise StopIteration
Example #13
0
    def decompositions(self, s):
        ((a, b, c), l) = s

        #                  r t r^tr = t_1 + t_2
        # \Rightleftarrow  t = r t_1 r^tr + r t_2 r^tr
        for a1 in xrange(a + 1):
            a2 = a - a1
            for c1 in xrange(c + 1):
                c2 = c - c1

                B1 = isqrt(4 * a1 * c1)
                B2 = isqrt(4 * a2 * c2)
                for b1 in xrange(max(-B1, b - B2), min(B1 + 1, b + B2 + 1)):
                    h1 = apply_GL_to_form(self.__p1list[l], (a1, b1, c1))
                    h2 = apply_GL_to_form(self.__p1list[l], (a2, b - b1, c2))
                    if h1[2] % self.__level == 0 and h2[2] % self.__level == 0:
                        yield ((h1, 1), (h2, 1))

        raise StopIteration
Example #14
0
 def iter_positive_forms(self) :
     if self.__reduced :
         ##TODO: This is really primitive. We barely reduce arbitrary forms.
         for diag in itertools.product(*[xrange(self.__bound) for _ in xrange(self.__n)]) :
             for subents in  itertools.product( *[ xrange(-2 * isqrt(diag[i] * diag[j]), 2 * isqrt(diag[i] * diag[j]) + 1)
                                                   for i in xrange(self.__n - 1) 
                                                   for j in xrange(i + 1, self.__n) ] ) :
                 t = matrix(ZZ, [[ 2 * diag[i]
                                   if i == j else
                                   (subents[self.__n * i - (i * (i + 1)) // 2 + j - i - 1]
                                    if i < j else
                                    subents[self.__n * j - (j * (j + 1)) // 2 + i - j - 1])
                                  for i in xrange(self.__n) ]
                                 for j in xrange(self.__n) ] )
 
                 t = self.__ambient.reduce(t)
                 if t is None : continue
                 t = t[0]
                 if t[0,0] == 0 : continue
                 
                 t.set_immutable()
                 
                 yield t
     else :
         for diag in itertools.product(*[xrange(self.__bound) for _ in xrange(self.__n)]) :
             for subents in  itertools.product( *[ xrange(-2 * isqrt(diag[i] * diag[j]), 2 * isqrt(diag[i] * diag[j]) + 1)
                                                   for i in xrange(self.__n - 1) 
                                                   for j in xrange(i + 1, self.__n) ] ) :
                 t = matrix(ZZ, [[ 2 * diag[i]
                                   if i == j else
                                   (subents[self.__n * i - (i * (i + 1)) // 2 + j - i - 1]
                                    if i < j else
                                    subents[self.__n * j - (j * (j + 1)) // 2 + i - j - 1])
                                  for i in xrange(self.__n) ]
                                 for j in xrange(self.__n) ] )
 
                 if self.__ambient._check_definiteness(t) != 1 :
                     continue
                 
                 t.set_immutable()
                 
                 yield t
Example #15
0
    def _kohnen_rho(self, t, a):
        dt = (-1)**(t.nrows() // 2) * t.det()
        d = fundamental_discriminant(dt)
        eps = isqrt(dt // d)

        res = 1
        for (p, e) in gcd(a, eps).factor():
            pol = self._kohnen_rho_polynomial(t, p).coefficients()
            if e < len(pol):
                res = res * pol[e]

        return res
Example #16
0
 def _kohnen_rho(self, t, a) :
     dt = (-1)**(t.nrows() // 2) * t.det()
     d = fundamental_discriminant(dt)
     eps = isqrt(dt // d)
     
     res = 1
     for (p,e) in gcd(a, eps).factor() :
         pol = self._kohnen_rho_polynomial(t, p).coefficients()
         if e < len(pol) :
             res = res * pol[e]
         
     return res
    def iter_indefinite_forms(self) :
        fm = Integer(4 * self.__m)
        
        if self.__reduced :
            if self.__weak_forms :
                msq = self.__m**2
                for n in xrange(0, min(self.__m // 4 + 1, self.__bound)) :
                    for r in xrange( isqrt(fm * n - 1) + 1 if n != 0 else 0,
                                     isqrt(fm * n + msq + 1) ) :
                        yield (n, r)
            else :

                for r in xrange(0, min(self.__m + 1,
                                       isqrt((self.__bound - 1) * fm) + 1) ) :
                    if fm.divides(r**2) :
                        yield (r**2 // fm, r)
        else :
            if self.__weak_forms :
                msq = self.__m**2
                for n in xrange(0, self.__bound) :
                    for r in xrange( isqrt(fm * n - 1) + 1 if n != 0 else 0,
                                     isqrt(fm * n + msq + 1) ) :
                        yield (n, r)
            else :
                for n in xrange(0, self.__bound) :
                    if (fm * n).is_square() :
                        yield(n, isqrt(fm * n))

        raise StopIteration
Example #18
0
    def iter_indefinite_forms(self) :
        fm = Integer(4 * self.__m)
        
        if self.__reduced :
            if self.__weak_forms :
                msq = self.__m**2
                for n in range(0, min(self.__m // 4 + 1, self.__bound)) :
                    for r in range( isqrt(fm * n - 1) + 1 if n != 0 else 0,
                                     isqrt(fm * n + msq + 1) ) :
                        yield (n, r)
            else :

                for r in range(0, min(self.__m + 1,
                                       isqrt((self.__bound - 1) * fm) + 1) ) :
                    if fm.divides(r**2) :
                        yield (r**2 // fm, r)
        else :
            if self.__weak_forms :
                msq = self.__m**2
                for n in range(0, self.__bound) :
                    for r in range( isqrt(fm * n - 1) + 1 if n != 0 else 0,
                                     isqrt(fm * n + msq + 1) ) :
                        yield (n, r)
            else :
                for n in range(0, self.__bound) :
                    if (fm * n).is_square() :
                        yield(n, isqrt(fm * n))

        raise StopIteration
Example #19
0
    def hz_pullback(self, mu):
        r"""
        Compute the pullbacks to Hirzebruch--Zagier curves.

        This computes the pullback f(\tau * \mu, \tau * \mu') of f to the embedded half-plane H * (\mu, \mu') where \mu' is the conjugate of \mu. The result is a modular form of level equal to the norm of \mu.

        INPUT:
        - ``mu`` -- a totally-positive integer in the base-field K.

        OUTPUT: an OrthogonalModularForm for a signature (2, 1) lattice

        WARNING: the output's weyl vector is not implemented

        EXAMPLES::

            sage: from weilrep import *
            sage: x = var('x')
            sage: K.<sqrt13> = NumberField(x * x - 13)
            sage: HMF(K).eisenstein_series(2, 15).hz_pullback(4 - sqrt13)
            1 + 24*q + O(q^2)
        """
        K = self.base_field()
        mu = K(mu)
        nn = mu.norm()
        tt = mu.trace()
        if tt <= 0 or nn <= 0:
            raise ValueError(
                'You called hz_pullback with a number that is not totally-positive!'
            )
        d = K.discriminant()
        a = isqrt((tt * tt - 4 * nn) / d)
        h = self.fourier_expansion()
        t, = PowerSeriesRing(QQ, 't').gens()
        d = K.discriminant()
        prec = floor(h.prec() / (tt / 2 + 2 * a / sqrt(d)))
        if d % 4:
            f = sum([
                p[n] * t**((i * tt + n * a) / 2)
                for i, p in enumerate(h.list()) for n in p.exponents()
            ]) + O(t**prec)
        else:
            f = sum([
                p[n] * t**((i * tt + 2 * n * a) / 2)
                for i, p in enumerate(h.list()) for n in p.exponents()
            ]) + O(t**prec)
        return OrthogonalModularFormLorentzian(self.weight(),
                                               WeilRep(matrix([[-2 * nn]])),
                                               f,
                                               scale=self.scale(),
                                               weylvec=vector([0]),
                                               qexp_representation='shimura')
Example #20
0
    def __iter__(self):
        if self.__disc is infinity:
            raise ValueError("infinity is not a true filter index")

        if self.__reduced:
            for c in range(0, self._indefinite_content_bound()):
                yield (0, 0, c)

            for a in range(1, isqrt(self.__disc // 3) + 1):
                for b in range(a + 1):
                    for c in range(a,
                                   (b**2 + (self.__disc - 1)) // (4 * a) + 1):
                        yield (a, b, c)
        else:
            ##FIXME: These are not all matrices
            for a in range(0, self._indefinite_content_bound()):
                yield (a, 0, 0)
            for c in range(1, self._indefinite_content_bound()):
                yield (0, 0, c)

            maxtrace = floor(5 * self.__disc / 15 + sqrt(self.__disc) / 2)
            for a in range(1, maxtrace + 1):
                for c in range(1, maxtrace - a + 1):
                    Bu = isqrt(4 * a * c - 1)

                    di = 4 * a * c - self.__disc
                    if di >= 0:
                        Bl = isqrt(di) + 1
                    else:
                        Bl = 0

                    for b in range(-Bu, -Bl + 1):
                        yield (a, b, c)
                    for b in range(Bl, Bu + 1):
                        yield (a, b, c)
        #! if self.__reduced

        raise StopIteration
Example #21
0
    def _iter_positive_forms_with_content_and_discriminant(self):
        if self.__disc is infinity:
            raise ValueError, "infinity is not a true filter index"

        if self.__reduced:
            for (l, (u, x)) in enumerate(self.__p1list):
                if u == 0:
                    for a in xrange(self.__level,
                                    isqrt(self.__disc // 4) + 1, self.__level):
                        frpa = 4 * a
                        for b in xrange(a + 1):
                            g = gcd(a // self.__level, b)
                            bsq = b**2

                            for c in xrange(a, (b**2 + (self.__disc - 1)) //
                                            (4 * a) + 1):
                                yield (((a, b, c), l), gcd(g,
                                                           c), frpa * c - bsq)
                else:
                    for a in xrange(1, isqrt(self.__disc // 3) + 1):
                        frpa = 4 * a
                        for b in xrange(a + 1):
                            g = gcd(a, b)
                            bsq = b**2

                            ## We need x**2 * a + x * b + c % N == 0
                            h = (-((x**2 + 1) * a + x * b)) % self.__level
                            for c in xrange(a + h,
                                            (b**2 + (self.__disc - 1)) //
                                            (4 * a) + 1, self.__level):
                                yield (((a, b, c), l),
                                       gcd(g, (x**2 * a + x * b + c) //
                                           self.__level), frpa * c - bsq)
        #! if self.__reduced
        else:
            raise NotImplementedError

        raise StopIteration
    def __init__(self, precision, level, reduced = True) :
        self.__level = level
        
        if isinstance(precision, ParamodularFormD2Filter_trace) :
            precision = precision.index()
        elif isinstance(precision, ParamodularFormD2Filter_discriminant) :
            if precision.index() is infinity :
                precision = infinity
            else :
                precision = isqrt(precision.index() - 1) + 1 

        self.__trace = precision
        self.__reduced = reduced
        self.__p1list = P1List(level)
 def iter_positive_forms(self) :
     r"""
     TESTS::
     
         sage: from psage.modform.jacobiforms.jacobiformd1nn_fourierexpansion import *
         sage: list(JacobiFormD1NNFilter(3, 2, reduced = True).iter_positive_forms())
         [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
         sage: list(JacobiFormD1NNFilter(3, 2, reduced = False).iter_positive_forms())
         [(1, 0), (1, 1), (1, -1), (1, 2), (1, -2), (2, 0), (2, 1), (2, -1), (2, 2), (2, -2), (2, 3), (2, -3)]
     """
     fm = 4 * self.__m
     if self.__reduced :
         for n in xrange(1, self.__bound) :
             for r in xrange(min(self.__m + 1, isqrt(fm * n - 1) + 1)) :
                 yield (n, r)
     else :
         for n in xrange(1, self.__bound) :
             yield(n, 0)
             for r in xrange(1, isqrt(fm * n - 1) + 1) :
                 yield (n, r)
                 yield (n, -r)
                     
     raise StopIteration
    def iter_positive_forms(self):
        r"""
        TESTS::
        
            sage: from psage.modform.jacobiforms.jacobiformd1nn_fourierexpansion import *
            sage: list(JacobiFormD1NNFilter(3, 2, reduced = True).iter_positive_forms())
            [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
            sage: list(JacobiFormD1NNFilter(3, 2, reduced = False).iter_positive_forms())
            [(1, 0), (1, 1), (1, -1), (1, 2), (1, -2), (2, 0), (2, 1), (2, -1), (2, 2), (2, -2), (2, 3), (2, -3)]
        """
        fm = 4 * self.__m
        if self.__reduced:
            for n in xrange(1, self.__bound):
                for r in xrange(min(self.__m + 1, isqrt(fm * n - 1) + 1)):
                    yield (n, r)
        else:
            for n in xrange(1, self.__bound):
                yield (n, 0)
                for r in xrange(1, isqrt(fm * n - 1) + 1):
                    yield (n, r)
                    yield (n, -r)

        raise StopIteration
Example #25
0
    def _calc_iter_reduced_sub3(self):
        try:
            return self.__iter_reduced_sub3
        except AttributeError:
            pass

        sub2 = self._calc_iter_reduced_sub2()

        sub3 = list()
        for (a0, a1, b01) in sub2:
            sub3s = list()
            for a2 in range(2, 2 * self.index(), 2):
                # obstruction for t[0,2]
                B1 = isqrt(a0 * a2 - 1)

                for b02 in range(-B1, B1 + 1):
                    # obstruction for t[1,2]
                    B3 = isqrt(a1 * a2 - 1)

                    for b12 in range(-B3, B3 + 1):
                        # obstruction for the minor [0,1,2] of t
                        if a0 * a1 * a2 - a0 * b12**2 + 2 * b01 * b12 * b02 - a2 * b01**2 - a1 * b02**2 <= 0:
                            continue

                        t = matrix(ZZ, 3,
                                   [a0, b01, b02, b01, a1, b12, b02, b12, a2])
                        u = t.LLL_gram()
                        if u.transpose() * t * u != t:
                            continue

                        sub3s.append((a2, b02, b12))

            sub3.append((a0, a1, b01, sub3s))

        self.__iter_reduced_sub3 = sub3

        return sub3
    def __iter__(self) :
        if self.__disc is infinity :
            raise ValueError, "infinity is not a true filter index"
        
        if self.__reduced :
            for c in xrange(0, self._indefinite_content_bound()) :
                yield (0,0,c)
                
            for a in xrange(1,isqrt(self.__disc // 3) + 1) :
                for b in xrange(a+1) :
                    for c in xrange(a, (b**2 + (self.__disc - 1))//(4*a) + 1) :
                        yield (a,b,c)
        else :
            ##FIXME: These are not all matrices
            for a in xrange(0, self._indefinite_content_bound()) :
                yield (a,0,0)
            for c in xrange(1, self._indefinite_content_bound()) :
                yield (0,0,c)
            
            maxtrace = floor(5*self.__disc / 15 + sqrt(self.__disc)/2)
            for a in xrange(1, maxtrace + 1) :
                for c in xrange(1, maxtrace - a + 1) :
                    Bu = isqrt(4*a*c - 1)

                    di = 4*a*c - self.__disc
                    if di >= 0 :
                        Bl = isqrt(di) + 1 
                    else :
                        Bl = 0
                    
                    for b in xrange(-Bu, -Bl + 1) :
                        yield (a,b,c)
                    for b in xrange(Bl, Bu + 1) :
                        yield (a,b,c)
        #! if self.__reduced
        
        raise StopIteration
Example #27
0
 def iter_positive_forms(self) :
     fm = 4 * self.__m
     if self.__reduced :
         if self.__weak_forms :
             msq = self.__m**2
             for n in range(1, self.__bound) :
                 for r in range(min(self.__m + 1, isqrt(fm * n + msq - 1) + 1)) :
                     yield (n, r)
         else :
             for n in range(1, self.__bound) :
                 for r in range(min(self.__m + 1, isqrt(fm * n - 1) + 1)) :
                     yield (n, r)
     else :
         if self.__weak_forms :
             msq = self.__m**2
             for n in range(1, self.__bound) :
                 for r in range(isqrt(fm * n + msq - 1) + 1) :
                     yield (n, r)
         else :
             for n in range(1, self.__bound) :
                 for r in range(isqrt(fm * n - 1) + 1) :
                     yield (n, r)
                     
     raise StopIteration
 def iter_positive_forms(self) :
     fm = 4 * self.__m
     if self.__reduced :
         if self.__weak_forms :
             msq = self.__m**2
             for n in xrange(1, self.__bound) :
                 for r in xrange(min(self.__m + 1, isqrt(fm * n + msq - 1) + 1)) :
                     yield (n, r)
         else :
             for n in xrange(1, self.__bound) :
                 for r in xrange(min(self.__m + 1, isqrt(fm * n - 1) + 1)) :
                     yield (n, r)
     else :
         if self.__weak_forms :
             msq = self.__m**2
             for n in xrange(1, self.__bound) :
                 for r in xrange(isqrt(fm * n + msq - 1) + 1) :
                     yield (n, r)
         else :
             for n in xrange(1, self.__bound) :
                 for r in xrange(isqrt(fm * n - 1) + 1) :
                     yield (n, r)
                     
     raise StopIteration
 def _calc_iter_reduced_sub3(self) :
     try :
         return self.__iter_reduced_sub3
     except AttributeError :
         pass
     
     sub2 = self._calc_iter_reduced_sub2()
     
     sub3 = list()
     for (a0, a1, b01) in sub2 :
         sub3s = list()
         for a2 in xrange(2, 2 * self.index(), 2) :
             # obstruction for t[0,2]
             B1 = isqrt(a0 * a2 - 1)
             
             for b02 in xrange(-B1, B1 + 1) :
                 # obstruction for t[1,2]
                 B3 = isqrt(a1 * a2 - 1)
                 
                 for b12 in xrange(-B3, B3 + 1) :
                     # obstruction for the minor [0,1,2] of t
                     if a0*a1*a2 - a0*b12**2 + 2*b01*b12*b02 - a2*b01**2 - a1*b02**2 <= 0 :
                         continue
                     
                     t = matrix(ZZ, 3, [a0, b01, b02, b01, a1, b12, b02, b12, a2])
                     u = t.LLL_gram()
                     if u.transpose() * t * u != t :
                         continue
                     
                     sub3s.append((a2, b02, b12))
                     
         sub3.append((a0, a1, b01, sub3s))
     
     self.__iter_reduced_sub3 = sub3
     
     return sub3
Example #30
0
 def init_ecdb_stats(self):
     if self._stats:
         return
     logger.debug("Computing elliptic curve stats...")
     ecdb = self.ecdb
     counts = self._counts
     stats = {}
     rank_counts = []
     for r in range(counts['max_rank']+1):
         ncu = ecdb.find({'rank': r}).count()
         ncl = ecdb.find({'rank': r, 'number': 1}).count()
         prop = format_percentage(ncl,counts['nclasses'])
         rank_counts.append({'r': r, 'ncurves': ncu, 'nclasses': ncl, 'prop': prop})
     stats['rank_counts'] = rank_counts
     tor_counts = []
     tor_counts2 = []
     ncurves = counts['ncurves']
     for t in  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16]:
         ncu = ecdb.find({'torsion': t}).count()
         if t in [4,8,12]: # two possible structures
             ncyc = ecdb.find({'torsion_structure': [str(t)]}).count()
             gp = "\(C_{%s}\)"%t
             prop = format_percentage(ncyc,ncurves)
             tor_counts.append({'t': t, 'gp': gp, 'ncurves': ncyc, 'prop': prop})
             nncyc = ncu-ncyc
             gp = "\(C_{2}\\times C_{%s}\)"%(t//2)
             prop = format_percentage(nncyc,ncurves)
             tor_counts2.append({'t': t, 'gp': gp, 'ncurves': nncyc, 'prop': prop})
         elif t==16: # all C_2 x C_8
             gp = "\(C_{2}\\times C_{8}\)"
             prop = format_percentage(ncu,ncurves)
             tor_counts2.append({'t': t, 'gp': gp, 'ncurves': ncu, 'prop': prop})
         else: # all cyclic
             gp = "\(C_{%s}\)"%t
             prop = format_percentage(ncu,ncurves)
             tor_counts.append({'t': t, 'gp': gp, 'ncurves': ncu, 'prop': prop})
     stats['tor_counts'] = tor_counts+tor_counts2
     stats['max_sha'] = ecdb.find().sort('sha', DESCENDING).limit(1)[0]['sha']
     sha_counts = []
     from sage.misc.functional import isqrt
     for s in range(1,1+isqrt(stats['max_sha'])):
         s2 = s*s
         nc = ecdb.find({'sha': s2}).count()
         if nc:
             sha_counts.append({'s': s, 'ncurves': nc})
     stats['sha_counts'] = sha_counts
     self._stats = stats
     logger.debug("... finished computing elliptic curve stats.")
Example #31
0
    def __iter__(self):
        r"""
        Iterate over all GL(2,Z)-reduced  semi positive forms
        which are within the bounds of this precision.

        EXAMPLES::

            sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
            sage: prec = SiegelModularFormPrecision(11)
            sage: for k in prec.__iter__(): print k
            (0, 0, 0)
            (0, 0, 1)
            (0, 0, 2)
            (1, 0, 1)
            (1, 0, 2)
            (1, 1, 1)
            (1, 1, 2)


        NOTE
            The forms are enumerated in lexicographic order.
        """
        if self.__type == 'disc':
            bound = self.get_contents_bound_for_semi_definite_forms()
            for c in range(0, bound):
                yield (0,0,c)

            atop = isqrt(self.__prec // 3)
            if 3*atop*atop == self.__prec: atop -= 1
            for a in range(1,atop + 1):
                for b in range(a+1):
                    for c in range(a, ceil((b**2 + self.__prec)/(4*a))):
                        yield (a,b,c)

        elif 'box' == self.__type:
            (am, bm, cm) = self.__prec
            for a in range(am):
                for b in range(min(bm,a+1)):
                    for c in range(a, cm):
                        yield (a,b,c)

        else:
            raise RuntimeError("Unexpected value of self.__type")
            
        raise StopIteration
    def __iter__(self):
        r"""
        Iterate over all GL(2,Z)-reduced  semi positive forms
        which are within the bounds of this precision.

        EXAMPLES::

            sage: from sage.modular.siegel.siegel_modular_form_prec import SiegelModularFormPrecision
            sage: prec = SiegelModularFormPrecision(11)
            sage: for k in prec.__iter__(): print k
            (0, 0, 0)
            (0, 0, 1)
            (0, 0, 2)
            (1, 0, 1)
            (1, 0, 2)
            (1, 1, 1)
            (1, 1, 2)


        NOTE
            The forms are enumerated in lexicographic order.
        """
        if self.__type == 'disc':
            bound = self.get_contents_bound_for_semi_definite_forms()
            for c in xrange(0, bound):
                yield (0,0,c)

            atop = isqrt(self.__prec // 3)
            if 3*atop*atop == self.__prec: atop -= 1
            for a in xrange(1,atop + 1):
                for b in xrange(a+1):
                    for c in xrange(a, ceil((b**2 + self.__prec)/(4*a))):
                        yield (a,b,c)

        elif 'box' == self.__type:
            (am, bm, cm) = self.__prec
            for a in xrange(am):
                for b in xrange( min(bm,a+1)):
                    for c in xrange(a, cm):
                        yield (a,b,c)

        else:
            raise RuntimeError, "Unexpected value of self.__type"
            
        raise StopIteration
Example #33
0
    def _calc_iter_reduced_sub2(self):
        try:
            return self.__iter_reduced_sub2
        except AttributeError:
            pass

        sub2 = list()
        for a0 in range(2, 2 * self.index(), 2):
            for a1 in range(a0, 2 * self.index(), 2):
                # obstruction for t[0,1]
                B1 = isqrt(a0 * a1 - 1)

                for b01 in range(0, min(B1, a0 // 2) + 1):
                    sub2.append((a0, a1, -b01))

        self.__iter_reduced_sub2 = sub2

        return sub2
def _jacobi_forms_by_taylor_expansion_coords(index, weight, precision) :
    global _jacobi_forms_by_taylor_expansion_coords_cache
    
    key = (index, weight)
    try :
        return _jacobi_forms_by_taylor_expansion_coords_cache[key]
    except KeyError :
        if precision < (index - 1) // 4 + 1 :
            precision = (index - 1) // 4 + 1
        
        weak_forms = _all_weak_jacobi_forms_by_taylor_expansion(index, weight, precision)
        weak_index_matrix = matrix(ZZ, [ [ f[(n,r)] for n in xrange((index - 1) // 4 + 1)
                                                    for r in xrange(isqrt(4 * n * index) + 1,  index + 1) ]
                                         for f in weak_forms] )
        _jacobi_forms_by_taylor_expansion_coords_cache[key] = \
          weak_index_matrix.left_kernel().echelonized_basis()
          
        return _jacobi_forms_by_taylor_expansion_coords_cache[key]
    def _calc_iter_reduced_sub2(self) :
        try :
            return self.__iter_reduced_sub2
        except AttributeError :
            pass
        
        sub2 = list()
        for a0 in xrange(2, 2 * self.index(), 2) :
            for a1 in xrange(a0, 2 * self.index(), 2) :
                # obstruction for t[0,1]
                B1 = isqrt(a0 * a1 - 1)
                
                for b01 in xrange(0, min(B1, a0 // 2) + 1) :
                    sub2.append((a0,a1,-b01))
        
        self.__iter_reduced_sub2 = sub2

        return sub2
Example #36
0
 def __init__( self, q):
     """
     We initialize by a list of integers $[a_1,...,a_N]$. The
     lattice self is then $L = (L,\beta) = (G^{-1}\ZZ^n/\ZZ^n, G[x])$,
     where $G$ is the symmetric matrix
     $G=[a_1,...,a_n;*,a_{n+1},....;..;* ... * a_N]$,
     i.e.~the $a_j$ denote the elements above the diagonal of $G$.
     """
     self.__form = q
     # We compute the rank
     N = len(q)
     assert is_square( 1+8*N)
     n = Integer( (-1+isqrt(1+8*N))/2)
     self.__rank = n
     # We set up the Gram matrix
     self.__G = matrix( IntegerRing(), n, n)
     i = j = 0
     for a in q:
         self.__G[i,j] = self.__G[j,i] = Integer(a)
         if j < n-1:
             j += 1
         else:
             i += 1
             j = i
     # We compute the level
     Gi = self.__G**-1
     self.__Gi = Gi
     a = lcm( map( lambda x: x.denominator(), Gi.list()))
     I = Gi.diagonal()
     b =  lcm( map( lambda x: (x/2).denominator(), I))
     self.__level = lcm( a, b)
     # We define the undelying module and the ambient space
     self.__module = FreeModule( IntegerRing(), n)
     self.__space = self.__module.ambient_vector_space()
     # We compute a shadow vector
     self.__shadow_vector = self.__space([(a%2)/2 for a in self.__G.diagonal()])*Gi
     # We define a basis
     M = Matrix( IntegerRing(), n, n, 1)
     self.__basis = self.__module.basis()
     # We prepare a cache
     self.__dual_vectors = None
     self.__values = None
     self.__chi = {}
Example #37
0
    def _kohnen_phi(self, a, t):
        ## We use a modified power of a, namely for each prime factor p of a
        ## we use p**floor(v_p(a)/2). This is compensated for in the routine
        ## of \rho
        a_modif = 1
        for (p, e) in a.factor():
            a_modif = a_modif * p**(e // 2)

        res = 0
        for dsq in [d for d in a.divisors() if d.is_square()]:
            d = isqrt(dsq)

            for g_diag in filter(
                    lambda diag: prod(diag) == d,
                    itertools.product(
                        *[d.divisors() for _ in range(t.nrows())])):
                for subents in itertools.product(*[
                        range(r) for (j, r) in enumerate(g_diag)
                        for _ in range(j)
                ]):
                    columns = [
                        subents[(j * (j - 1)) // 2:(j * (j + 1)) // 2]
                        for j in range(t.nrows())
                    ]
                    g = diagonal_matrix(list(g_diag))
                    for j in range(t.nrows()):
                        for i in range(j):
                            g[i, j] = columns[j][i]

                    ginv = g.inverse()
                    tg = ginv.transpose() * t * ginv
                    try:
                        tg = matrix(ZZ, tg)
                    except:
                        continue
                    if any(tg[i, i] % 2 == 1 for i in range(tg.nrows())):
                        continue

                    tg.set_immutable()

                    res = res + self._kohnen_rho(tg, a // dsq)

        return a_modif * res
Example #38
0
def _jacobi_forms_by_taylor_expansion_coords(index, weight, precision):
    global _jacobi_forms_by_taylor_expansion_coords_cache

    key = (index, weight)
    try:
        return _jacobi_forms_by_taylor_expansion_coords_cache[key]
    except KeyError:
        if precision < (index - 1) // 4 + 1:
            precision = (index - 1) // 4 + 1

        weak_forms = _all_weak_jacobi_forms_by_taylor_expansion(
            index, weight, precision)
        weak_index_matrix = matrix(ZZ, [[
            f[(n, r)] for n in xrange((index - 1) // 4 + 1)
            for r in xrange(isqrt(4 * n * index) + 1, index + 1)
        ] for f in weak_forms])
        _jacobi_forms_by_taylor_expansion_coords_cache[key] = \
          weak_index_matrix.left_kernel().echelonized_basis()

        return _jacobi_forms_by_taylor_expansion_coords_cache[key]
    def decompositions(self, s):
        (n, r) = s

        fm = 4 * self.__m
        if self.__weak_forms:
            yield ((0, 0), (n, r))
            yield ((n, r), (0, 0))

            msq = self.__m**2
            for n1 in xrange(1, n):
                n2 = n - n1
                for r1 in xrange(
                        max(r - isqrt(fm * n2 + msq),
                            isqrt(fm * n1 + msq - 1) + 1),
                        min(r + isqrt(fm * n2 + msq) + 1,
                            isqrt(fm * n1 + msq) + 1)):
                    yield ((n1, r1), (n2, r - r1))
        else:
            yield ((0, 0), (n, r))
            yield ((n, r), (0, 0))

            for n1 in xrange(1, n):
                n2 = n - n1
                ##r = r1 + r2
                ##r1**2 <= 4 n1 m
                ## (r - r1)**2 <= 4 n2 m
                ## r1**2 - 2*r1*r + r**2 - 4 m n2 <= 0
                ## r1 <-> r \pm \sqrt{r**2 - r**2 + 4 m n2}
                for r1 in xrange(
                        max(r - isqrt(fm * n2),
                            isqrt(fm * n1 - 1) + 1),
                        min(r + isqrt(fm * n2) + 1,
                            isqrt(fm * n1) + 1)):
                    yield ((n1, r1), (n2, r - r1))

        raise StopIteration
Example #40
0
    def iter_positive_forms(self):
        if self.__disc is infinity:
            raise ValueError("infinity is not a true filter index")

        if self.__reduced:
            for (l, (u, x)) in enumerate(self.__p1list):
                if u == 0:
                    for a in range(self.__level, self.__trace, self.__level):
                        for c in range(a, self.__trace - a):
                            for b in range(
                                    2 * isqrt(a * c - 1) +
                                    2 if a * c != 1 else 1, 2 * isqrt(a * c)):
                                yield ((a, b, c), l)
                else:
                    for a in range(1, self.__trace):
                        for b in range(a + 1):
                            ## We need x**2 * a + x * b + c % N == 0
                            h = ((x**2 + 1) * a + x * b) % self.__level
                            if x == 0 and h == 0: h = 1
                            for c in range(
                                    h, self.__trace - x * b - (x**2 + 1) * a,
                                    self.__level):
                                yield ((a, b, c), l)
        #! if self.__reduced
        else:
            for (l, (u, x)) in enumerate(self.__p1list):
                if u == 0:
                    for a in range(self.__level, self.__trace, self.__level):
                        for c in range(1, self.__trace - a):
                            for b in range(
                                    2 * isqrt(a * c - 1) +
                                    2 if a * c != 1 else 1, 2 * isqrt(a * c)):
                                yield ((a, b, c), l)
                else:
                    for a in range(1, self.__trace):
                        for c in range(self.__level, self.__trace - a,
                                       self.__level):
                            for b in range(
                                    2 * isqrt(a * c - 1) +
                                    2 if a * c != 1 else 1, 2 * isqrt(a * c)):
                                yield ((a, b - 2 * x * a,
                                        c - x * b - x**2 * a), l)
        #! else self.__reduced

        raise StopIteration
 def iter_positive_forms(self) :
     if self.__disc is infinity :
         raise ValueError, "infinity is not a true filter index"
     
     if self.__reduced :
         for (l, (u,x)) in enumerate(self.__p1list) :
             if u == 0 :
                 for a in xrange(self.__level, self.__trace, self.__level) :
                     for c in xrange(a, self.__trace - a) :
                         for b in xrange( 2 * isqrt(a * c - 1) + 2 if a*c != 1 else 1,
                                          2 * isqrt(a * c) ) :
                             yield ((a,b,c), l)
             else :
                 for a in xrange(1, self.__trace) :
                     for b in xrange(a+1) :
                         ## We need x**2 * a + x * b + c % N == 0
                         h = ((x**2 + 1) * a + x * b) % self.__level
                         if x == 0 and h == 0 : h = 1
                         for c in xrange( h, self.__trace - x * b - (x**2  + 1) * a, self.__level ) :
                             yield ((a,b,c), l)
     #! if self.__reduced
     else :
         for (l, (u,x)) in enumerate(self.__p1list) :
             if u == 0 :
                 for a in xrange(self.__level, self.__trace, self.__level) :
                     for c in xrange(1, self.__trace - a) :
                         for b in xrange( 2 * isqrt(a * c - 1) + 2 if a*c != 1 else 1,
                                          2 * isqrt(a * c) ) :
                             yield ((a,b,c), l)
             else :
                 for a in xrange(1, self.__trace) :
                     for c in xrange(self.__level, self.__trace - a, self.__level) :
                         for b in xrange( 2 * isqrt(a * c - 1) + 2 if a*c != 1 else 1,
                                          2 * isqrt(a * c) ) :
                             yield ((a, b - 2 * x * a, c - x * b - x**2 * a), l)
     #! else self.__reduced
     
     raise StopIteration
Example #42
0
    def init_ecdb_stats(self):
        if self._stats:
            return
        logger.debug("Computing elliptic curve stats...")
        ecdbstats = db.ec_curves.stats
        counts = self._counts
        stats = {}
        rank_counts = []
        rdict = dict(ecdbstats.get_oldstat('rank')['counts'])
        crdict = dict(ecdbstats.get_oldstat('class/rank')['counts'])
        for r in range(counts['max_rank']+1):
            try:
                ncu = rdict[str(r)]
                ncl = crdict[str(r)]
            except KeyError:
                ncu = rdict[r]
                ncl = crdict[r]
            prop = format_percentage(ncl,counts['nclasses'])
            rank_counts.append({'r': r, 'ncurves': ncu, 'nclasses': ncl, 'prop': prop})
        stats['rank_counts'] = rank_counts
        tor_counts = []
        tor_counts2 = []
        ncurves = counts['ncurves']
        tdict = dict(ecdbstats.get_oldstat('torsion')['counts'])
        tsdict = dict(ecdbstats.get_oldstat('torsion_structure')['counts'])
        for t in  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16]:
            try:
                ncu = tdict[t]
            except KeyError:
                ncu = tdict[str(t)]
            if t in [4,8,12]: # two possible structures
                ncyc = tsdict[str(t)]
                gp = "\(C_{%s}\)"%t
                prop = format_percentage(ncyc,ncurves)
                tor_counts.append({'t': t, 'gp': gp, 'ncurves': ncyc, 'prop': prop})
                nncyc = ncu-ncyc
                gp = "\(C_{2}\\times C_{%s}\)"%(t//2)
                prop = format_percentage(nncyc,ncurves)
                tor_counts2.append({'t': t, 'gp': gp, 'ncurves': nncyc, 'prop': prop})
            elif t==16: # all C_2 x C_8
                gp = "\(C_{2}\\times C_{8}\)"
                prop = format_percentage(ncu,ncurves)
                tor_counts2.append({'t': t, 'gp': gp, 'ncurves': ncu, 'prop': prop})
            else: # all cyclic
                gp = "\(C_{%s}\)"%t
                prop = format_percentage(ncu,ncurves)
                tor_counts.append({'t': t, 'gp': gp, 'ncurves': ncu, 'prop': prop})
        stats['tor_counts'] = tor_counts+tor_counts2

        shadict = dict(ecdbstats.get_oldstat('sha')['counts'])
        stats['max_sha'] = max([int(s) for s in shadict])
        sha_counts = []
        from sage.misc.functional import isqrt
        sha_is_int = True
        try:
            nc = shadict[1]
        except KeyError:
            sha_is_int = False
        for s in range(1,1+isqrt(stats['max_sha'])):
            s2 = s*s
            if sha_is_int:
                nc = shadict.get(s2,0)
            else:
                nc = shadict.get(str(s2),0)
            if nc:
                sha_counts.append({'s': s, 'ncurves': nc})
        stats['sha_counts'] = sha_counts
        self._stats = stats
        logger.debug("... finished computing elliptic curve stats.")
Example #43
0
    def maass_form(self, f, g, k=None, is_integral=False):
        r"""
        Return the Siegel modular form `I(f,g)` (Notation as in [Sko]).
    
        INPUT:
        - `f`              -- modular form of level `1`
        - `g`              -- cusp form of level `1` and weight = ``weight of f + 2``
        - ``is_integral``  -- ``True`` if the result is garanteed to have integer
                              coefficients
        """

        ## we introduce an abbreviations
        if is_integral:
            PS = self.integral_power_series_ring()
        else:
            PS = self.power_series_ring()

        fismodular = isinstance(f, ModularFormElement)
        gismodular = isinstance(g, ModularFormElement)

        ## We only check the arguments if f and g are ModularFormElements.
        ## Otherwise we trust in the user
        if fismodular and gismodular:
            assert( f.weight() + 2 == g.weight() | (f==0) | (g==0)), \
                    "incorrect weights!"
            assert (
                g.q_expansion(1) == 0), "second argument is not a cusp form"

        qexp_prec = self._get_maass_form_qexp_prec()
        if qexp_prec is None:  # there are no forms below prec
            return dict()

        if fismodular:
            k = f.weight()
            if f == f.parent()(0):
                f = PS(0, qexp_prec)
            else:
                f = PS(f.qexp(qexp_prec), qexp_prec)
        elif f == 0:
            f = PS(0, qexp_prec)
        else:
            f = PS(f(qexp_prec), qexp_prec)

        if gismodular:
            k = g.weight() - 2
            if g == g.parent()(0):
                g = PS(0, qexp_prec)
            else:
                g = PS(g.qexp(qexp_prec), qexp_prec)
        elif g == 0:
            g = PS(0, qexp_prec)
        else:
            g = PS(g(qexp_prec), qexp_prec)

        if k is None:
            raise ValueError, "if neither f nor g are not ModularFormElements " + \
                              "you must pass k"

        fderiv = f.derivative().shift(1)
        f *= Integer(k / 2)
        gfderiv = g - fderiv

        ## Form A and B - the Jacobi forms used in [Sko]'s I map.
        ## This is not necessary if we multiply Ifg0 and Ifg1 by etapow
        # (A0,A1,B0,B1) = (a0*etapow, a1*etapow, b0*etapow, b1*etapow)

        ## Calculate the image of the pair of modular forms (f,g) under
        ## [Sko]'s isomorphism I : M_{k} \oplus S_{k+2} -> J_{k,1}.

        # Multiplication of big polynomials may take > 60 GB, so wie have
        # to do it in small parts; This is only implemented for integral
        # coefficients.
        """
        Create the Jacobi form I(f,g) as in [Sko].
    
        It suffices to construct for all Jacobi forms phi only the part
        sum_{r=0,1;n} c_phi(r^2-4n) q^n zeta^r.
        When, in this code part, we speak of Jacobi form we only mean this part.
        
        We need to compute Ifg = \sum_{r=0,1; n} c(r^2-4n) q^n zeta^r up to
        4n-r^2 <= Dtop, i.e. n < precision
        """

        ## Create the Jacobi forms A=a*etapow and B=b*etapow in stages.
        ## Recall a = sum_{s != r mod 2} s^2*(-1)^r*q^((s^2+r^2-1)/4)*zeta^r
        ##        b = sum_{s != r mod 2}     (-1)^r*q^((s^2+r^2-1)/4)*zeta^r
        ## r, s run over ZZ but with opposite parities.
        ## For r=0, we need s odd, (s^2-1)/4 < precision, with s=2t+1 hence t^2+t < precision.
        ## For r=1, we need s even, s^2/4 < precision, with s=2t hence t^2 < precision.

        ## we use a slightly overestimated ab_prec

        ab_prec = isqrt(qexp_prec + 1)
        a1dict = dict()
        a0dict = dict()
        b1dict = dict()
        b0dict = dict()

        for t in xrange(1, ab_prec + 1):
            tmp = t**2
            a1dict[tmp] = -8 * tmp
            b1dict[tmp] = -2

            tmp += t
            a0dict[tmp] = 8 * tmp + 2
            b0dict[tmp] = 2
        b1dict[0] = -1
        a0dict[0] = 2
        b0dict[0] = 2

        a1 = PS(a1dict)
        b1 = PS(b1dict)
        a0 = PS(a0dict)
        b0 = PS(b0dict)

        ## Finally: I(f,g) is given by the formula below:
        ## We multiply by etapow explecitely and save two multiplications
        # Ifg0 = k/2*f*A0 - fderiv*B0 + g*B0 + O(q^precision)
        # Ifg1 = k/2*f*A1 - fderiv*B1 + g*B1 + O(q^precision)
        Ifg0 = (self._eta_power() * (f * a0 + gfderiv * b0)).list()
        Ifg1 = (self._eta_power() * (f * a1 + gfderiv * b1)).list()

        if len(Ifg0) < qexp_prec:
            Ifg0 += [0] * (qexp_prec - len(Ifg0))
        if len(Ifg1) < qexp_prec:
            Ifg1 += [0] * (qexp_prec - len(Ifg1))

        ## For applying the Maass' lifting to genus 2 modular forms.
        ## we put the coefficients of Ifg into a dictionary Chi
        ## so that we can access the coefficient corresponding to
        ## discriminant D by going Chi[D].

        Cphi = dict([(0, 0)])
        for i in xrange(qexp_prec):
            Cphi[-4 * i] = Ifg0[i]
            Cphi[1 - 4 * i] = Ifg1[i]

        del Ifg0[:], Ifg1[:]
        """
        Create the Maas lift F := VI(f,g) as in [Sko].
        """

        ## The constant term is given by -Cphi[0]*B_{2k}/(4*k)
        ## (note in [Sko] this coeff has typos).
        ## For nonconstant terms,
        ## The Siegel coefficient of q^n * zeta^r * qdash^m is given
        ## by the formula  \sum_{ a | gcd(n,r,m) } Cphi[D/a^2] where
        ## D = r^2-4*n*m is the discriminant.
        ## Hence in either case the coefficient
        ## is fully deterimined by the pair (D,gcd(n,r,m)).
        ## Put (D,t) -> \sum_{ a | t } Cphi[D/a^2]
        ## in a dictionary (hash table) maassc.

        maass_coeffs = dict()
        divisor_dict = self._divisor_dict()

        ## First calculate maass coefficients corresponding to strictly positive definite matrices:
        for disc in self._negative_fundamental_discriminants():
            for s in xrange(
                    1,
                    isqrt((-self.__precision.discriminant()) // disc) + 1):
                ## add (disc*s^2,t) as a hash key, for each t that divides s
                for t in divisor_dict[s]:
                    maass_coeffs[(disc * s**2,t)] = \
                       sum( a**(k-1) * Cphi[disc * s**2 / a**2]
                            for a in divisor_dict[t] )

        ## Compute the coefficients of the Siegel form $F$:
        siegel_coeffs = dict()
        for (n, r,
             m), g in self.__precision.iter_positive_forms_with_content():
            siegel_coeffs[(n, r, m)] = maass_coeffs[(r**2 - 4 * m * n, g)]

        ## Secondly, deal with the singular part.
        ## Include the coeff corresponding to (0,0,0):
        ## maass_coeffs = {(0,0): -bernoulli(k)/(2*k)*Cphi[0]}
        siegel_coeffs[(0, 0, 0)] = -bernoulli(k) / (2 * k) * Cphi[0]
        if is_integral:
            siegel_coeffs[(0, 0, 0)] = Integer(siegel_coeffs[(0, 0, 0)])

        ## Calculate the other discriminant-zero maass coefficients.
        ## Since sigma is quite cheap it is faster to estimate the bound and
        ## save the time for repeated calculation
        for i in xrange(1, self.__precision._indefinite_content_bound()):
            ## maass_coeffs[(0,i)] = sigma(i, k-1) * Cphi[0]
            siegel_coeffs[(0, 0, i)] = sigma(i, k - 1) * Cphi[0]

        return siegel_coeffs
Example #44
0
    def init_ecdb_stats(self):
        if self._stats:
            return
        logger.debug("Computing elliptic curve stats...")
        ecdbstats = db.ec_curves.stats
        counts = self._counts
        stats = {}
        rank_counts = []
        rdict = dict(ecdbstats.get_oldstat('rank')['counts'])
        crdict = dict(ecdbstats.get_oldstat('class/rank')['counts'])
        for r in range(counts['max_rank'] + 1):
            try:
                ncu = rdict[str(r)]
                ncl = crdict[str(r)]
            except KeyError:
                ncu = rdict[r]
                ncl = crdict[r]
            prop = format_percentage(ncl, counts['nclasses'])
            rank_counts.append({
                'r': r,
                'ncurves': ncu,
                'nclasses': ncl,
                'prop': prop
            })
        stats['rank_counts'] = rank_counts
        tor_counts = []
        tor_counts2 = []
        ncurves = counts['ncurves']
        tdict = dict(ecdbstats.get_oldstat('torsion')['counts'])
        tsdict = dict(ecdbstats.get_oldstat('torsion_structure')['counts'])
        for t in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 16]:
            try:
                ncu = tdict[t]
            except KeyError:
                ncu = tdict[str(t)]
            if t in [4, 8, 12]:  # two possible structures
                ncyc = tsdict[str(t)]
                gp = "\(C_{%s}\)" % t
                prop = format_percentage(ncyc, ncurves)
                tor_counts.append({
                    't': t,
                    'gp': gp,
                    'ncurves': ncyc,
                    'prop': prop
                })
                nncyc = ncu - ncyc
                gp = "\(C_{2}\\times C_{%s}\)" % (t // 2)
                prop = format_percentage(nncyc, ncurves)
                tor_counts2.append({
                    't': t,
                    'gp': gp,
                    'ncurves': nncyc,
                    'prop': prop
                })
            elif t == 16:  # all C_2 x C_8
                gp = "\(C_{2}\\times C_{8}\)"
                prop = format_percentage(ncu, ncurves)
                tor_counts2.append({
                    't': t,
                    'gp': gp,
                    'ncurves': ncu,
                    'prop': prop
                })
            else:  # all cyclic
                gp = "\(C_{%s}\)" % t
                prop = format_percentage(ncu, ncurves)
                tor_counts.append({
                    't': t,
                    'gp': gp,
                    'ncurves': ncu,
                    'prop': prop
                })
        stats['tor_counts'] = tor_counts + tor_counts2

        shadict = dict(ecdbstats.get_oldstat('sha')['counts'])
        stats['max_sha'] = max([int(s) for s in shadict])
        sha_counts = []
        from sage.misc.functional import isqrt
        sha_is_int = True
        try:
            nc = shadict[1]
        except KeyError:
            sha_is_int = False
        for s in range(1, 1 + isqrt(stats['max_sha'])):
            s2 = s * s
            if sha_is_int:
                nc = shadict.get(s2, 0)
            else:
                nc = shadict.get(str(s2), 0)
            if nc:
                sha_counts.append({'s': s, 'ncurves': nc})
        stats['sha_counts'] = sha_counts
        self._stats = stats
        logger.debug("... finished computing elliptic curve stats.")
    def maass_form( self, f, g, k = None, is_integral = False) :
        r"""
        Return the Siegel modular form `I(f,g)` (Notation as in [Sko]).
    
        INPUT:
        - `f`              -- modular form of level `1`
        - `g`              -- cusp form of level `1` and weight = ``weight of f + 2``
        - ``is_integral``  -- ``True`` if the result is garanteed to have integer
                              coefficients
        """
        
        ## we introduce an abbreviations
        if is_integral :
            PS = self.integral_power_series_ring()
        else :
            PS = self.power_series_ring()
        
        fismodular = isinstance(f, ModularFormElement)
        gismodular = isinstance(g, ModularFormElement)
    
        ## We only check the arguments if f and g are ModularFormElements.
        ## Otherwise we trust in the user 
        if fismodular and gismodular :
            assert( f.weight() + 2 == g.weight() | (f==0) | (g==0)), \
                    "incorrect weights!"
            assert( g.q_expansion(1) == 0), "second argument is not a cusp form"

        qexp_prec = self._get_maass_form_qexp_prec()
        if qexp_prec is None : # there are no forms below prec
            return dict()

        if fismodular :
            k = f.weight()
            if f == f.parent()(0) :
                f = PS(0, qexp_prec)
            else :
                f = PS(f.qexp(qexp_prec), qexp_prec)
        elif f == 0 :
            f = PS(0, qexp_prec)
        else :
            f = PS(f(qexp_prec), qexp_prec)
        
        if gismodular :
            k = g.weight() - 2
            if g == g.parent()(0) :
                g = PS(0, qexp_prec)
            else :
                g = PS(g.qexp(qexp_prec), qexp_prec)
        elif g == 0 :
            g = PS(0, qexp_prec)
        else :
            g = PS(g(qexp_prec), qexp_prec)
                
        if k is None :
            raise ValueError, "if neither f nor g are not ModularFormElements " + \
                              "you must pass k"
            
        fderiv = f.derivative().shift(1)
        f *= Integer(k/2)
        gfderiv = g - fderiv

        ## Form A and B - the Jacobi forms used in [Sko]'s I map.
        ## This is not necessary if we multiply Ifg0 and Ifg1 by etapow
        # (A0,A1,B0,B1) = (a0*etapow, a1*etapow, b0*etapow, b1*etapow)
    
        ## Calculate the image of the pair of modular forms (f,g) under
        ## [Sko]'s isomorphism I : M_{k} \oplus S_{k+2} -> J_{k,1}.
        
        # Multiplication of big polynomials may take > 60 GB, so wie have
        # to do it in small parts; This is only implemented for integral
        # coefficients.

        """
        Create the Jacobi form I(f,g) as in [Sko].
    
        It suffices to construct for all Jacobi forms phi only the part
        sum_{r=0,1;n} c_phi(r^2-4n) q^n zeta^r.
        When, in this code part, we speak of Jacobi form we only mean this part.
        
        We need to compute Ifg = \sum_{r=0,1; n} c(r^2-4n) q^n zeta^r up to
        4n-r^2 <= Dtop, i.e. n < precision
        """

        ## Create the Jacobi forms A=a*etapow and B=b*etapow in stages.
        ## Recall a = sum_{s != r mod 2} s^2*(-1)^r*q^((s^2+r^2-1)/4)*zeta^r
        ##        b = sum_{s != r mod 2}     (-1)^r*q^((s^2+r^2-1)/4)*zeta^r
        ## r, s run over ZZ but with opposite parities.
        ## For r=0, we need s odd, (s^2-1)/4 < precision, with s=2t+1 hence t^2+t < precision.
        ## For r=1, we need s even, s^2/4 < precision, with s=2t hence t^2 < precision.
    
        ## we use a slightly overestimated ab_prec 
        
        ab_prec = isqrt(qexp_prec + 1)
        a1dict = dict(); a0dict = dict()
        b1dict = dict(); b0dict = dict()
    
        for t in xrange(1, ab_prec + 1) :
            tmp = t**2
            a1dict[tmp] = -8*tmp
            b1dict[tmp] = -2
        
            tmp += t
            a0dict[tmp] = 8*tmp + 2
            b0dict[tmp] = 2
        b1dict[0] = -1
        a0dict[0] = 2; b0dict[0] = 2 
        
        a1 = PS(a1dict); b1 = PS(b1dict)
        a0 = PS(a0dict); b0 = PS(b0dict)

        ## Finally: I(f,g) is given by the formula below:
        ## We multiply by etapow explecitely and save two multiplications
        # Ifg0 = k/2*f*A0 - fderiv*B0 + g*B0 + O(q^precision)
        # Ifg1 = k/2*f*A1 - fderiv*B1 + g*B1 + O(q^precision)
        Ifg0 = (self._eta_power() * (f*a0 + gfderiv*b0)).list()
        Ifg1 = (self._eta_power() * (f*a1 + gfderiv*b1)).list()

        if len(Ifg0) < qexp_prec :
            Ifg0 += [0]*(qexp_prec - len(Ifg0))
        if len(Ifg1) < qexp_prec :
            Ifg1 += [0]*(qexp_prec - len(Ifg1))
        
        ## For applying the Maass' lifting to genus 2 modular forms.
        ## we put the coefficients of Ifg into a dictionary Chi
        ## so that we can access the coefficient corresponding to 
        ## discriminant D by going Chi[D].
        
        Cphi = dict([(0,0)])
        for i in xrange(qexp_prec) :
            Cphi[-4*i] = Ifg0[i]
            Cphi[1-4*i] = Ifg1[i]

        del Ifg0[:], Ifg1[:]

        """
        Create the Maas lift F := VI(f,g) as in [Sko].
        """
        
        ## The constant term is given by -Cphi[0]*B_{2k}/(4*k)
        ## (note in [Sko] this coeff has typos).
        ## For nonconstant terms,
        ## The Siegel coefficient of q^n * zeta^r * qdash^m is given 
        ## by the formula  \sum_{ a | gcd(n,r,m) } Cphi[D/a^2] where 
        ## D = r^2-4*n*m is the discriminant.  
        ## Hence in either case the coefficient 
        ## is fully deterimined by the pair (D,gcd(n,r,m)).
        ## Put (D,t) -> \sum_{ a | t } Cphi[D/a^2]
        ## in a dictionary (hash table) maassc.

        maass_coeffs = dict()
        divisor_dict = self._divisor_dict()

        ## First calculate maass coefficients corresponding to strictly positive definite matrices:        
        for disc in self._negative_fundamental_discriminants() :
            for s in xrange(1, isqrt((-self.__precision.discriminant()) // disc) + 1) :
                ## add (disc*s^2,t) as a hash key, for each t that divides s
                for t in divisor_dict[s] :
                    maass_coeffs[(disc * s**2,t)] = \
                       sum( a**(k-1) * Cphi[disc * s**2 / a**2] 
                            for a in divisor_dict[t] )

        ## Compute the coefficients of the Siegel form $F$:
        siegel_coeffs = dict()
        for (n,r,m), g in self.__precision.iter_positive_forms_with_content() :
            siegel_coeffs[(n,r,m)] = maass_coeffs[(r**2 - 4*m*n, g)]

        ## Secondly, deal with the singular part.
        ## Include the coeff corresponding to (0,0,0):
        ## maass_coeffs = {(0,0): -bernoulli(k)/(2*k)*Cphi[0]}
        siegel_coeffs[(0,0,0)] = -bernoulli(k)/(2*k)*Cphi[0]
        if is_integral :
            siegel_coeffs[(0,0,0)] = Integer(siegel_coeffs[(0,0,0)])
        
        ## Calculate the other discriminant-zero maass coefficients.
        ## Since sigma is quite cheap it is faster to estimate the bound and
        ## save the time for repeated calculation
        for i in xrange(1, self.__precision._indefinite_content_bound()) :
            ## maass_coeffs[(0,i)] = sigma(i, k-1) * Cphi[0]
            siegel_coeffs[(0,0,i)] = sigma(i, k-1) * Cphi[0]

        return siegel_coeffs
 def iter_positive_forms(self) :
     if self.__disc is infinity :
         raise ValueError, "infinity is not a true filter index"
     
     if self.__reduced :
         for (l, (u,x)) in enumerate(self.__p1list) :
             if u == 0 :
                 for a in xrange(self.__level, isqrt(self.__disc // 4) + 1, self.__level) :
                     for b in xrange(a+1) :
                         for c in xrange(a, (b**2 + (self.__disc - 1))//(4*a) + 1) :
                             yield ((a,b,c), l)
             else :
                 for a in xrange(1, isqrt(self.__disc // 3) + 1) :
                     for b in xrange(a+1) :
                         ## We need x**2 * a + x * b + c % N == 0
                         h = (-((x**2 + 1) * a + x * b)) % self.__level
                         for c in xrange( a + h,
                                          (b**2 + (self.__disc - 1))//(4*a) + 1, self.__level ) :
                             yield ((a,b,c), l)
     #! if self.__reduced
     else :
         maxtrace = floor(self.__disc / Integer(3) + sqrt(self.__disc / Integer(3)))
         for (l, (u,x)) in enumerate(self.__p1list) :
             if u == 0 :
                 for a in xrange(self.__level, maxtrace + 1, self.__level) :
                     for c in xrange(1, maxtrace - a + 1) :
                         Bu = isqrt(4*a*c - 1)
     
                         di = 4*a*c - self.__disc
                         if di >= 0 :
                             Bl = isqrt(di) + 1 
                         else :
                             Bl = 0
                         
                         for b in xrange(-Bu, -Bl + 1) :
                             yield ((a,b,c), l)
                         for b in xrange(Bl, Bu + 1) :
                             yield ((a,b,c), l)
             else :
                 for a in xrange(1, maxtrace + 1) :
                     for c in xrange(1, maxtrace - a + 1) :
                         Bu = isqrt(4*a*c - 1)
     
                         di = 4*a*c - self.__disc
                         if di >= 0 :
                             Bl = isqrt(di) + 1 
                         else :
                             Bl = 0
                         
                         h = (-x * a - int(Mod(x, self.__level)**-1) * c - Bu) % self.__level \
                             if x != 0 else \
                             (-Bu) % self.__level
                         for b in xrange(-Bu + self.__level - h, -Bl + 1, self.__level) :
                             yield ((a,b,c), l)
                         h = (-x * a - int(Mod(x, self.__level)**-1) * c + Bl) % self.__level \
                             if x !=0 else \
                             Bl % self.__level
                         for b in xrange(Bl + self.__level - h, Bu + 1, self.__level) :
                             yield ((a,b,c), l)
     #! else self.__reduced
     
     raise StopIteration
Example #47
0
    def _by_taylor_expansion_m1(self, f_divs, k, is_integral=False):
        r"""
        This provides faster implementation of by_taylor_expansion in the case
        of Jacobi index `1` (and even weight). It avoids the computation of the
        Wronskian by providing an explicit formula.
        """
        raise RuntimeError(
            "This code is known to have a bug. Use, for example,JacobiFormD1NNFactory_class._test__by_taylor_expansion(200, 10, 1) to check."
        )

        if is_integral:
            PS = self.integral_power_series_ring()
        else:
            PS = self.power_series_ring()

        qexp_prec = self._qexp_precision()

        fderiv = f_divs[(0, 0)].derivative().shift(1)
        f = f_divs[(0, 0)] * Integer(k / 2)
        gfderiv = f_divs[(1, 0)] - fderiv

        ab_prec = isqrt(qexp_prec + 1)
        a1dict = dict()
        a0dict = dict()
        b1dict = dict()
        b0dict = dict()

        for t in xrange(1, ab_prec + 1):
            tmp = t**2
            a1dict[tmp] = -8 * tmp
            b1dict[tmp] = -2

            tmp += t
            a0dict[tmp] = 8 * tmp + 2
            b0dict[tmp] = 2
        b1dict[0] = -1
        a0dict[0] = 2
        b0dict[0] = 2

        a1 = PS(a1dict)
        b1 = PS(b1dict)
        a0 = PS(a0dict)
        b0 = PS(b0dict)

        Ifg0 = (self._wronskian_invdeterminant() *
                (f * a0 + gfderiv * b0)).list()
        Ifg1 = (self._wronskian_invdeterminant() *
                (f * a1 + gfderiv * b1)).list()

        if len(Ifg0) < qexp_prec:
            Ifg0 += [0] * (qexp_prec - len(Ifg0))
        if len(Ifg1) < qexp_prec:
            Ifg1 += [0] * (qexp_prec - len(Ifg1))

        Cphi = dict([(0, 0)])
        for i in xrange(qexp_prec):
            Cphi[-4 * i] = Ifg0[i]
            Cphi[1 - 4 * i] = Ifg1[i]

        del Ifg0[:], Ifg1[:]

        phi_coeffs = dict()
        for r in xrange(2):
            for n in xrange(qexp_prec):
                k = 4 * n - r**2
                if k >= 0:
                    phi_coeffs[(n, r)] = Cphi[-k]

        return phi_coeffs
    def _theta_factors(self, p = None) :
        r"""
        Return the factor `W^\# (\theta_0, .., \theta_{2m - 1})^{\mathrm{T}}` as a list.
        The `q`-expansion is shifted by `-(m + 1)(2*m + 1) / 24` which will be compensated
        for by the eta factor.
        """
        try :
            if p is None :
                return self.__theta_factors
            else :
                P = PowerSeriesRing(GF(p), 'q')
                
                return [map(P, facs) for facs in self.__theta_factors] 

        except AttributeError :
            qexp_prec = self._qexp_precision()
            if p is None :
                PS = self.integral_power_series_ring()
            else :
                PS = PowerSeriesRing(GF(p), 'q')
            m = self.__precision.jacobi_index()
            
            twom = 2 * m
            frmsq = twom ** 2
            
            thetas = dict( ((i, j), dict())
                           for i in xrange(m + 1) for j in xrange(m + 1) )
            
            ## We want to calculate \hat \theta_{j,l} = sum_r (2 m r + j)**2l q**(m r**2 + j r).

            for r in xrange(0, isqrt((qexp_prec - 1 + m)//m) + 2) :
                for j in [0,m] :
                    fact = (twom*r + j)**2
                    coeff = 2
                    for l in xrange(0, m + 1) :
                        thetas[(j,l)][m*r**2 + r*j] = coeff
                        coeff = coeff * fact
            thetas[(0,0)][0] = 1
                    
            for r in xrange(0, isqrt((qexp_prec - 1 + m)//m) + 2) :
                for j in xrange(1, m) :
                    fact_p = (twom*r + j)**2
                    fact_m = (twom*r - j)**2
                    coeff_p = 2
                    coeff_m = 2
                    
                    for l in xrange(0, m + 1) :
                        thetas[(j,l)][m*r**2 + r*j] = coeff_p 
                        thetas[(j,l)][m*r**2 - r*j] = coeff_m
                        coeff_p = coeff_p * fact_p
                        coeff_m = coeff_m * fact_m 
                                    
            thetas = dict( ( k, PS(th).add_bigoh(qexp_prec) )
                           for (k,th) in thetas.iteritems() )
            
            W = matrix(PS, m + 1, [ thetas[(j, l)]
                                    for j in xrange(m + 1) for l in xrange(m + 1) ])
            
            
            ## Since the adjoint of matrices with entries in a general ring
            ## is extremely slow for matrices of small size, we hard code the
            ## the cases `m = 2` and `m = 3`.  The expressions are obtained by
            ## computing the adjoint of a matrix with entries `w_{i,j}` in a
            ## polynomial algebra.
            if m == 2 and qexp_prec > 10**5 :
                adj00 =   W[1,1] * W[2,2] - W[2,1] * W[1,2]
                adj01 = - W[1,0] * W[2,2] + W[2,0] * W[1,2]
                adj02 =   W[1,0] * W[2,1] - W[2,0] * W[1,1]
                adj10 = - W[0,1] * W[2,2] + W[2,1] * W[0,2]
                adj11 =   W[0,0] * W[2,2] - W[2,0] * W[0,2]
                adj12 = - W[0,0] * W[2,1] + W[2,0] * W[0,1]
                adj20 =   W[0,1] * W[1,2] - W[1,1] * W[0,2]
                adj21 = - W[0,0] * W[1,2] + W[1,0] * W[0,2]
                adj22 =   W[0,0] * W[1,1] - W[1,0] * W[0,1]

                Wadj = matrix(PS, [ [adj00, adj01, adj02],
                                    [adj10, adj11, adj12],
                                    [adj20, adj21, adj22] ])
                  
            elif m == 3 and qexp_prec > 10**5 :
                adj00 = -W[0,2]*W[1,1]*W[2,0] + W[0,1]*W[1,2]*W[2,0] + W[0,2]*W[1,0]*W[2,1] - W[0,0]*W[1,2]*W[2,1] - W[0,1]*W[1,0]*W[2,2] + W[0,0]*W[1,1]*W[2,2]
                adj01 = -W[0,3]*W[1,1]*W[2,0] + W[0,1]*W[1,3]*W[2,0] + W[0,3]*W[1,0]*W[2,1] - W[0,0]*W[1,3]*W[2,1] - W[0,1]*W[1,0]*W[2,3] + W[0,0]*W[1,1]*W[2,3]
                adj02 = -W[0,3]*W[1,2]*W[2,0] + W[0,2]*W[1,3]*W[2,0] + W[0,3]*W[1,0]*W[2,2] - W[0,0]*W[1,3]*W[2,2] - W[0,2]*W[1,0]*W[2,3] + W[0,0]*W[1,2]*W[2,3]
                adj03 = -W[0,3]*W[1,2]*W[2,1] + W[0,2]*W[1,3]*W[2,1] + W[0,3]*W[1,1]*W[2,2] - W[0,1]*W[1,3]*W[2,2] - W[0,2]*W[1,1]*W[2,3] + W[0,1]*W[1,2]*W[2,3]

                adj10 = -W[0,2]*W[1,1]*W[3,0] + W[0,1]*W[1,2]*W[3,0] + W[0,2]*W[1,0]*W[3,1] - W[0,0]*W[1,2]*W[3,1] - W[0,1]*W[1,0]*W[3,2] + W[0,0]*W[1,1]*W[3,2]
                adj11 = -W[0,3]*W[1,1]*W[3,0] + W[0,1]*W[1,3]*W[3,0] + W[0,3]*W[1,0]*W[3,1] - W[0,0]*W[1,3]*W[3,1] - W[0,1]*W[1,0]*W[3,3] + W[0,0]*W[1,1]*W[3,3]
                adj12 = -W[0,3]*W[1,2]*W[3,0] + W[0,2]*W[1,3]*W[3,0] + W[0,3]*W[1,0]*W[3,2] - W[0,0]*W[1,3]*W[3,2] - W[0,2]*W[1,0]*W[3,3] + W[0,0]*W[1,2]*W[3,3]
                adj13 = -W[0,3]*W[1,2]*W[3,1] + W[0,2]*W[1,3]*W[3,1] + W[0,3]*W[1,1]*W[3,2] - W[0,1]*W[1,3]*W[3,2] - W[0,2]*W[1,1]*W[3,3] + W[0,1]*W[1,2]*W[3,3]

                adj20 = -W[0,2]*W[2,1]*W[3,0] + W[0,1]*W[2,2]*W[3,0] + W[0,2]*W[2,0]*W[3,1] - W[0,0]*W[2,2]*W[3,1] - W[0,1]*W[2,0]*W[3,2] + W[0,0]*W[2,1]*W[3,2]
                adj21 = -W[0,3]*W[2,1]*W[3,0] + W[0,1]*W[2,3]*W[3,0] + W[0,3]*W[2,0]*W[3,1] - W[0,0]*W[2,3]*W[3,1] - W[0,1]*W[2,0]*W[3,3] + W[0,0]*W[2,1]*W[3,3]
                adj22 = -W[0,3]*W[2,2]*W[3,0] + W[0,2]*W[2,3]*W[3,0] + W[0,3]*W[2,0]*W[3,2] - W[0,0]*W[2,3]*W[3,2] - W[0,2]*W[2,0]*W[3,3] + W[0,0]*W[2,2]*W[3,3]
                adj23 = -W[0,3]*W[2,2]*W[3,1] + W[0,2]*W[2,3]*W[3,1] + W[0,3]*W[2,1]*W[3,2] - W[0,1]*W[2,3]*W[3,2] - W[0,2]*W[2,1]*W[3,3] + W[0,1]*W[2,2]*W[3,3]

                adj30 = -W[1,2]*W[2,1]*W[3,0] + W[1,1]*W[2,2]*W[3,0] + W[1,2]*W[2,0]*W[3,1] - W[1,0]*W[2,2]*W[3,1] - W[1,1]*W[2,0]*W[3,2] + W[1,0]*W[2,1]*W[3,2]
                adj31 = -W[1,3]*W[2,1]*W[3,0] + W[1,1]*W[2,3]*W[3,0] + W[1,3]*W[2,0]*W[3,1] - W[1,0]*W[2,3]*W[3,1] - W[1,1]*W[2,0]*W[3,3] + W[1,0]*W[2,1]*W[3,3]
                adj32 = -W[1,3]*W[2,2]*W[3,0] + W[1,2]*W[2,3]*W[3,0] + W[1,3]*W[2,0]*W[3,2] - W[1,0]*W[2,3]*W[3,2] - W[1,2]*W[2,0]*W[3,3] + W[1,0]*W[2,2]*W[3,3]
                adj33 = -W[1,3]*W[2,2]*W[3,1] + W[1,2]*W[2,3]*W[3,1] + W[1,3]*W[2,1]*W[3,2] - W[1,1]*W[2,3]*W[3,2] - W[1,2]*W[2,1]*W[3,3] + W[1,1]*W[2,2]*W[3,3]

                Wadj = matrix(PS, [ [adj00, adj01, adj02, adj03],
                                    [adj10, adj11, adj12, adj13],
                                    [adj20, adj21, adj22, adj23],
                                    [adj30, adj31, adj32, adj33] ])
            else :
                Wadj = W.adjoint()
            
            theta_factors = [ [ Wadj[i,r] for i in xrange(m + 1) ]
                              for r in xrange(m + 1) ]
            
            if p is None :
                self.__theta_factors = theta_factors
                
            return theta_factors
Example #49
0
    def _by_taylor_expansion_m1(self, f_divs, k, is_integral=False):
        r"""
        This provides special, faster code in the Jacobi index `1` case.
        """
        if is_integral:
            PS = self.integral_power_series_ring()
        else:
            PS = self.power_series_ring()

        qexp_prec = self._qexp_precision()

        fderiv = f_divs[(0, 0)].derivative().shift(1)
        f = f_divs[(0, 0)] * Integer(k / 2)
        gfderiv = f_divs[(1, 0)] - fderiv

        ab_prec = isqrt(qexp_prec + 1)
        a1dict = dict()
        a0dict = dict()
        b1dict = dict()
        b0dict = dict()

        for t in xrange(1, ab_prec + 1):
            tmp = t**2
            a1dict[tmp] = -8 * tmp
            b1dict[tmp] = -2

            tmp += t
            a0dict[tmp] = 8 * tmp + 2
            b0dict[tmp] = 2
        b1dict[0] = -1
        a0dict[0] = 2
        b0dict[0] = 2

        a1 = PS(a1dict)
        b1 = PS(b1dict)
        a0 = PS(a0dict)
        b0 = PS(b0dict)

        Ifg0 = (self._eta_factor() * (f * a0 + gfderiv * b0)).list()
        Ifg1 = (self._eta_factor() * (f * a1 + gfderiv * b1)).list()

        if len(Ifg0) < qexp_prec:
            Ifg0 += [0] * (qexp_prec - len(Ifg0))
        if len(Ifg1) < qexp_prec:
            Ifg1 += [0] * (qexp_prec - len(Ifg1))

        Cphi = dict([(0, 0)])
        for i in xrange(qexp_prec):
            Cphi[-4 * i] = Ifg0[i]
            Cphi[1 - 4 * i] = Ifg1[i]

        del Ifg0[:], Ifg1[:]

        phi_coeffs = dict()
        m = self.__precision.jacobi_index()
        for r in xrange(2 * self.__precision.jacobi_index()):
            for n in xrange(qexp_prec):
                k = 4 * m * n - r**2
                if k >= 0:
                    phi_coeffs[(n, r)] = Cphi[-k]

        return phi_coeffs
Example #50
0
    def __iter__(self):
        if self.index() is infinity:
            raise ValueError("infinity is not a true filter index")

        if self.is_reduced():
            ## We only iterate positive definite matrices
            ## and later build the semidefinite ones
            ## We first find possible upper left matrices

            sub2 = self._calc_iter_reduced_sub2()
            sub3 = self._calc_iter_reduced_sub3()
            sub4 = self._calc_iter_reduced_sub4()

            t = zero_matrix(ZZ, 4)
            t.set_immutable()
            yield t

            for a0 in range(2, 2 * self.index(), 2):
                t = zero_matrix(ZZ, 4)
                t[3, 3] = a0
                t.set_immutable()

                yield t

            for (a0, a1, b01) in sub2:
                t = zero_matrix(ZZ, 4)
                t[2, 2] = a0
                t[3, 3] = a1
                t[2, 3] = b01
                t[3, 2] = b01
                t.set_immutable()

                yield t

            for (a0, a1, b01, sub3s) in sub3:
                t = zero_matrix(ZZ, 4)
                t[1, 1] = a0
                t[2, 2] = a1
                t[1, 2] = b01
                t[2, 1] = b01

                for (a2, b02, b12) in sub3s:
                    ts = copy(t)
                    ts[3, 3] = a2
                    ts[1, 3] = b02
                    ts[3, 1] = b02
                    ts[2, 3] = b12
                    ts[3, 2] = b12
                    ts.set_immutable()

                    yield ts

            for (a0, a1, b01, sub4s) in sub4:
                t = zero_matrix(ZZ, 4)
                t[0, 0] = a0
                t[1, 1] = a1
                t[0, 1] = b01
                t[1, 0] = b01

                for (a2, b02, b12, sub4ss) in sub4s:
                    ts = copy(t)
                    ts[2, 2] = a2
                    ts[0, 2] = b02
                    ts[2, 0] = b02
                    ts[1, 2] = b12
                    ts[2, 1] = b12

                    for (a3, b03, b13, b23) in sub4ss:
                        tss = copy(ts)
                        tss[3, 3] = a3
                        tss[0, 1] = b01
                        tss[1, 0] = b01
                        tss[0, 2] = b02
                        tss[2, 0] = b02
                        tss[0, 3] = b03
                        tss[3, 0] = b03
                        tss.set_immutable()

                        yield tss

        #! if self.is_reduced()
        else:
            ## We first find possible upper left matrices

            sub2 = list()
            for a0 in range(2 * self.index(), 2):
                for a1 in range(2 * self.index(), 2):
                    # obstruction for t[0,1]
                    B1 = isqrt(a0 * a1)

                    for b01 in range(-B1, B1 + 1):
                        sub2.append((a0, a1, b01))

            sub3 = list()
            for (a0, a1, b01) in sub2:
                sub3s = list()
                for a2 in range(2 * self.index(), 2):
                    # obstruction for t[0,2]
                    B1 = isqrt(a0 * a2)

                    for b02 in range(-B1, B1 + 1):
                        # obstruction for t[1,2]
                        B3 = isqrt(a1 * a2)

                        for b12 in range(-B3, B3 + 1):
                            # obstruction for the minor [0,1,2] of t
                            if a0 * a1 * a2 - a0 * b12**2 + 2 * b01 * b12 * b02 - b01**2 * a2 - a1 * b02**2 < 0:
                                continue
                            sub3s.append((a2, b02, b12))
                sub3.append((a0, a1, b01, sub3s))

            for (a0, a1, b01, sub3s) in sub3:
                for (a2, b02, b12) in sub3s:
                    for a3 in range(2 * self.index(), 2):
                        # obstruction for t[0,3]
                        B1 = isqrt(a0 * a3)

                        for b03 in range(-B1, B1 + 1):
                            # obstruction for t[1,3]
                            B3 = isqrt(a1 * a3)

                            for b13 in range(-B3, B3 + 1):
                                # obstruction for the minor [0,1,3] of t
                                if a0 * a1 * a3 - a0 * b13**2 + 2 * b01 * b13 * b03 - b01**2 * a3 - a1 * b03**2 < 0:
                                    continue

                                # obstruction for t[2,3]
                                B3 = isqrt(a2 * a3)

                                for b23 in range(-B3, B3 + 1):
                                    # obstruction for the minor [0,2,3] of t
                                    if a0 * a2 * a3 - a0 * b23**2 + 2 * b02 * b23 * b03 - b02**2 * a3 - a2 * b03**2 < 0:
                                        continue

                                    # obstruction for the minor [1,2,3] of t
                                    if a1 * a2 * a3 - a1 * b23**2 + 2 * b12 * b23 * b13 - b12**2 * a3 - a2 * b13**2 < 0:
                                        continue

                                    t = matrix(ZZ,
                                               4, [
                                                   a0, b01, b02, b03, b01, a1,
                                                   b12, b13, b02, b12, a2, b23,
                                                   b03, b13, b23, a3
                                               ],
                                               check=False)
                                    if t.det() < 0:
                                        continue

                                    t.set_immutable()

                                    yield t

        raise StopIteration
Example #51
0
    def _theta_factors(self, p=None):
        r"""
        Return the factor `W^\# (\theta_0, .., \theta_{2m - 1})^{\mathrm{T}}` as a list.
        The `q`-expansion is shifted by `-(m + 1)(2*m + 1) / 24` which will be compensated
        for by the eta factor.
        """
        try:
            if p is None:
                return self.__theta_factors
            else:
                P = PowerSeriesRing(GF(p), 'q')

                return [map(P, facs) for facs in self.__theta_factors]

        except AttributeError:
            qexp_prec = self._qexp_precision()
            if p is None:
                PS = self.integral_power_series_ring()
            else:
                PS = PowerSeriesRing(GF(p), 'q')
            m = self.__precision.jacobi_index()

            twom = 2 * m
            frmsq = twom**2

            thetas = dict(
                ((i, j), dict()) for i in xrange(m + 1) for j in xrange(m + 1))

            ## We want to calculate \hat \theta_{j,l} = sum_r (2 m r + j)**2l q**(m r**2 + j r).

            for r in xrange(0, isqrt((qexp_prec - 1 + m) // m) + 2):
                for j in [0, m]:
                    fact = (twom * r + j)**2
                    coeff = 2
                    for l in xrange(0, m + 1):
                        thetas[(j, l)][m * r**2 + r * j] = coeff
                        coeff = coeff * fact
            thetas[(0, 0)][0] = 1

            for r in xrange(0, isqrt((qexp_prec - 1 + m) // m) + 2):
                for j in xrange(1, m):
                    fact_p = (twom * r + j)**2
                    fact_m = (twom * r - j)**2
                    coeff_p = 2
                    coeff_m = 2

                    for l in xrange(0, m + 1):
                        thetas[(j, l)][m * r**2 + r * j] = coeff_p
                        thetas[(j, l)][m * r**2 - r * j] = coeff_m
                        coeff_p = coeff_p * fact_p
                        coeff_m = coeff_m * fact_m

            thetas = dict((k, PS(th).add_bigoh(qexp_prec))
                          for (k, th) in thetas.iteritems())

            W = matrix(
                PS, m + 1,
                [thetas[(j, l)] for j in xrange(m + 1) for l in xrange(m + 1)])

            ## Since the adjoint of matrices with entries in a general ring
            ## is extremely slow for matrices of small size, we hard code the
            ## the cases `m = 2` and `m = 3`.  The expressions are obtained by
            ## computing the adjoint of a matrix with entries `w_{i,j}` in a
            ## polynomial algebra.
            if m == 2 and qexp_prec > 10**5:
                adj00 = W[1, 1] * W[2, 2] - W[2, 1] * W[1, 2]
                adj01 = -W[1, 0] * W[2, 2] + W[2, 0] * W[1, 2]
                adj02 = W[1, 0] * W[2, 1] - W[2, 0] * W[1, 1]
                adj10 = -W[0, 1] * W[2, 2] + W[2, 1] * W[0, 2]
                adj11 = W[0, 0] * W[2, 2] - W[2, 0] * W[0, 2]
                adj12 = -W[0, 0] * W[2, 1] + W[2, 0] * W[0, 1]
                adj20 = W[0, 1] * W[1, 2] - W[1, 1] * W[0, 2]
                adj21 = -W[0, 0] * W[1, 2] + W[1, 0] * W[0, 2]
                adj22 = W[0, 0] * W[1, 1] - W[1, 0] * W[0, 1]

                Wadj = matrix(PS,
                              [[adj00, adj01, adj02], [adj10, adj11, adj12],
                               [adj20, adj21, adj22]])

            elif m == 3 and qexp_prec > 10**5:
                adj00 = -W[0, 2] * W[1, 1] * W[2, 0] + W[0, 1] * W[1, 2] * W[
                    2, 0] + W[0, 2] * W[1, 0] * W[2, 1] - W[0, 0] * W[
                        1, 2] * W[2, 1] - W[0, 1] * W[1, 0] * W[2, 2] + W[
                            0, 0] * W[1, 1] * W[2, 2]
                adj01 = -W[0, 3] * W[1, 1] * W[2, 0] + W[0, 1] * W[1, 3] * W[
                    2, 0] + W[0, 3] * W[1, 0] * W[2, 1] - W[0, 0] * W[
                        1, 3] * W[2, 1] - W[0, 1] * W[1, 0] * W[2, 3] + W[
                            0, 0] * W[1, 1] * W[2, 3]
                adj02 = -W[0, 3] * W[1, 2] * W[2, 0] + W[0, 2] * W[1, 3] * W[
                    2, 0] + W[0, 3] * W[1, 0] * W[2, 2] - W[0, 0] * W[
                        1, 3] * W[2, 2] - W[0, 2] * W[1, 0] * W[2, 3] + W[
                            0, 0] * W[1, 2] * W[2, 3]
                adj03 = -W[0, 3] * W[1, 2] * W[2, 1] + W[0, 2] * W[1, 3] * W[
                    2, 1] + W[0, 3] * W[1, 1] * W[2, 2] - W[0, 1] * W[
                        1, 3] * W[2, 2] - W[0, 2] * W[1, 1] * W[2, 3] + W[
                            0, 1] * W[1, 2] * W[2, 3]

                adj10 = -W[0, 2] * W[1, 1] * W[3, 0] + W[0, 1] * W[1, 2] * W[
                    3, 0] + W[0, 2] * W[1, 0] * W[3, 1] - W[0, 0] * W[
                        1, 2] * W[3, 1] - W[0, 1] * W[1, 0] * W[3, 2] + W[
                            0, 0] * W[1, 1] * W[3, 2]
                adj11 = -W[0, 3] * W[1, 1] * W[3, 0] + W[0, 1] * W[1, 3] * W[
                    3, 0] + W[0, 3] * W[1, 0] * W[3, 1] - W[0, 0] * W[
                        1, 3] * W[3, 1] - W[0, 1] * W[1, 0] * W[3, 3] + W[
                            0, 0] * W[1, 1] * W[3, 3]
                adj12 = -W[0, 3] * W[1, 2] * W[3, 0] + W[0, 2] * W[1, 3] * W[
                    3, 0] + W[0, 3] * W[1, 0] * W[3, 2] - W[0, 0] * W[
                        1, 3] * W[3, 2] - W[0, 2] * W[1, 0] * W[3, 3] + W[
                            0, 0] * W[1, 2] * W[3, 3]
                adj13 = -W[0, 3] * W[1, 2] * W[3, 1] + W[0, 2] * W[1, 3] * W[
                    3, 1] + W[0, 3] * W[1, 1] * W[3, 2] - W[0, 1] * W[
                        1, 3] * W[3, 2] - W[0, 2] * W[1, 1] * W[3, 3] + W[
                            0, 1] * W[1, 2] * W[3, 3]

                adj20 = -W[0, 2] * W[2, 1] * W[3, 0] + W[0, 1] * W[2, 2] * W[
                    3, 0] + W[0, 2] * W[2, 0] * W[3, 1] - W[0, 0] * W[
                        2, 2] * W[3, 1] - W[0, 1] * W[2, 0] * W[3, 2] + W[
                            0, 0] * W[2, 1] * W[3, 2]
                adj21 = -W[0, 3] * W[2, 1] * W[3, 0] + W[0, 1] * W[2, 3] * W[
                    3, 0] + W[0, 3] * W[2, 0] * W[3, 1] - W[0, 0] * W[
                        2, 3] * W[3, 1] - W[0, 1] * W[2, 0] * W[3, 3] + W[
                            0, 0] * W[2, 1] * W[3, 3]
                adj22 = -W[0, 3] * W[2, 2] * W[3, 0] + W[0, 2] * W[2, 3] * W[
                    3, 0] + W[0, 3] * W[2, 0] * W[3, 2] - W[0, 0] * W[
                        2, 3] * W[3, 2] - W[0, 2] * W[2, 0] * W[3, 3] + W[
                            0, 0] * W[2, 2] * W[3, 3]
                adj23 = -W[0, 3] * W[2, 2] * W[3, 1] + W[0, 2] * W[2, 3] * W[
                    3, 1] + W[0, 3] * W[2, 1] * W[3, 2] - W[0, 1] * W[
                        2, 3] * W[3, 2] - W[0, 2] * W[2, 1] * W[3, 3] + W[
                            0, 1] * W[2, 2] * W[3, 3]

                adj30 = -W[1, 2] * W[2, 1] * W[3, 0] + W[1, 1] * W[2, 2] * W[
                    3, 0] + W[1, 2] * W[2, 0] * W[3, 1] - W[1, 0] * W[
                        2, 2] * W[3, 1] - W[1, 1] * W[2, 0] * W[3, 2] + W[
                            1, 0] * W[2, 1] * W[3, 2]
                adj31 = -W[1, 3] * W[2, 1] * W[3, 0] + W[1, 1] * W[2, 3] * W[
                    3, 0] + W[1, 3] * W[2, 0] * W[3, 1] - W[1, 0] * W[
                        2, 3] * W[3, 1] - W[1, 1] * W[2, 0] * W[3, 3] + W[
                            1, 0] * W[2, 1] * W[3, 3]
                adj32 = -W[1, 3] * W[2, 2] * W[3, 0] + W[1, 2] * W[2, 3] * W[
                    3, 0] + W[1, 3] * W[2, 0] * W[3, 2] - W[1, 0] * W[
                        2, 3] * W[3, 2] - W[1, 2] * W[2, 0] * W[3, 3] + W[
                            1, 0] * W[2, 2] * W[3, 3]
                adj33 = -W[1, 3] * W[2, 2] * W[3, 1] + W[1, 2] * W[2, 3] * W[
                    3, 1] + W[1, 3] * W[2, 1] * W[3, 2] - W[1, 1] * W[
                        2, 3] * W[3, 2] - W[1, 2] * W[2, 1] * W[3, 3] + W[
                            1, 1] * W[2, 2] * W[3, 3]

                Wadj = matrix(PS, [[adj00, adj01, adj02, adj03],
                                   [adj10, adj11, adj12, adj13],
                                   [adj20, adj21, adj22, adj23],
                                   [adj30, adj31, adj32, adj33]])
            else:
                Wadj = W.adjoint()

            theta_factors = [[Wadj[i, r] for i in xrange(m + 1)]
                             for r in xrange(m + 1)]

            if p is None:
                self.__theta_factors = theta_factors

            return theta_factors
Example #52
0
    def decompositions(self, t):
        ## We find all decompositions t1 + t2 = t
        ## We first find possible upper left matrices

        sub2 = list()
        for a0 in range(0, t[0, 0] + 1, 2):
            for a1 in range(0, t[1, 1] + 1, 2):
                # obstruction for t1[0,1]
                B1 = isqrt(a0 * a1)
                # obstruction for t2[0,1]
                B2 = isqrt((t[0, 0] - a0) * (t[1, 1] - a1))

                for b01 in range(max(-B1, t[0, 1] - B2),
                                 min(B1, t[0, 1] + B2) + 1):
                    sub2.append((a0, a1, b01))

        sub3 = list()
        for (a0, a1, b01) in sub2:
            sub3s = list()
            for a2 in range(0, t[2, 2] + 1, 2):
                # obstruction for t1[0,2]
                B1 = isqrt(a0 * a2)
                # obstruction for t2[0,2]
                B2 = isqrt((t[0, 0] - a0) * (t[2, 2] - a2))

                for b02 in range(max(-B1, t[0, 2] - B2),
                                 min(B1, t[0, 2] + B2) + 1):
                    # obstruction for t1[1,2]
                    B3 = isqrt(a1 * a2)
                    # obstruction for t2[1,2]
                    B4 = isqrt((t[1, 1] - a1) * (t[2, 2] - a2))

                    for b12 in range(max(-B3, t[1, 2] - B4),
                                     min(B3, t[1, 2] + B4) + 1):
                        # obstruction for the minor [0,1,2] of t1
                        if a0 * a1 * a2 - a0 * b12**2 + 2 * b01 * b12 * b02 - b01**2 * a2 - a1 * b02**2 < 0:
                            continue
                        # obstruction for the minor [0,1,2] of t2
                        if  (t[0,0] - a0)*(t[1,1] - a1)*(t[2,2] - a2) - (t[0,0] - a0)*(t[1,2] - b12)**2 \
                           + 2*(t[0,1] - b01)*(t[1,2] - b12)*(t[0,2] - b02) - (t[0,1] - b01)**2*(t[2,2] - a2) \
                           - (t[1,1] - a1)*(t[0,2] - b02)**2 < 0:
                            continue
                        sub3s.append((a2, b02, b12))
            sub3.append((a0, a1, b01, sub3s))

        for (a0, a1, b01, sub3s) in sub3:
            for (a2, b02, b12) in sub3s:
                for a3 in range(0, t[3, 3] + 1, 2):
                    # obstruction for t1[0,3]
                    B1 = isqrt(a0 * a3)
                    # obstruction for t2[0,3]
                    B2 = isqrt((t[0, 0] - a0) * (t[3, 3] - a3))

                    for b03 in range(max(-B1, t[0, 3] - B2),
                                     min(B1, t[0, 3] + B2) + 1):
                        # obstruction for t1[1,3]
                        B3 = isqrt(a1 * a3)
                        # obstruction for t2[1,3]
                        B4 = isqrt((t[1, 1] - a1) * (t[3, 3] - a3))

                        for b13 in range(max(-B3, t[1, 3] - B4),
                                         min(B3, t[1, 3] + B4) + 1):
                            # obstruction for the minor [0,1,3] of t1
                            if a0 * a1 * a3 - a0 * b13**2 + 2 * b01 * b13 * b03 - b01**2 * a3 - a1 * b03**2 < 0:
                                continue
                            # obstruction for the minor [0,1,3] of t2
                            if  (t[0,0] - a0)*(t[1,1] - a1)*(t[3,3] - a3) - (t[0,0] - a0)*(t[1,3] - b13)**2 \
                               + 2*(t[0,1] - b01)*(t[1,3] - b13)*(t[0,3] - b03) - (t[0,1] - b01)**2*(t[3,3] - a3) \
                               - (t[1,1] - a1)*(t[0,3] - b03)**2 < 0:
                                continue

                            # obstruction for t1[2,3]
                            B3 = isqrt(a2 * a3)
                            # obstruction for t2[2,3]
                            B4 = isqrt((t[2, 2] - a2) * (t[3, 3] - a3))

                            for b23 in range(max(-B3, t[2, 3] - B4),
                                             min(B3, t[2, 3] + B4) + 1):
                                # obstruction for the minor [0,2,3] of t1
                                if a0 * a2 * a3 - a0 * b23**2 + 2 * b02 * b23 * b03 - b02**2 * a3 - a2 * b03**2 < 0:
                                    continue
                                # obstruction for the minor [0,2,3] of t2
                                if  (t[0,0] - a0)*(t[2,2] - a2)*(t[3,3] - a3) - (t[0,0] - a0)*(t[2,3] - b23)**2 \
                                   + 2*(t[0,2] - b02)*(t[2,3] - b23)*(t[0,3] - b03) - (t[0,2] - b02)**2*(t[3,3] - a3) \
                                   - (t[2,2] - a2)*(t[0,3] - b03)**2 < 0:
                                    continue

                                # obstruction for the minor [1,2,3] of t1
                                if a1 * a2 * a3 - a1 * b23**2 + 2 * b12 * b23 * b13 - b12**2 * a3 - a2 * b13**2 < 0:
                                    continue
                                # obstruction for the minor [1,2,3] of t2
                                if  (t[1,1] - a1)*(t[2,2] - a2)*(t[3,3] - a3) - (t[1,1] - a1)*(t[2,3] - b23)**2 \
                                   + 2*(t[1,2] - b12)*(t[2,3] - b23)*(t[1,3] - b13) - (t[1,2] - b12)**2*(t[3,3] - a3) \
                                   - (t[2,2] - a2)*(t[1,3] - b13)**2 < 0:
                                    continue

                                t1 = matrix(
                                    ZZ,
                                    4, [
                                        a0, b01, b02, b03, b01, a1, b12, b13,
                                        b02, b12, a2, b23, b03, b13, b23, a3
                                    ],
                                    check=False)
                                if t1.det() < 0:
                                    continue
                                t2 = t - t1
                                if t2.det() < 0:
                                    continue

                                t1.set_immutable()
                                t2.set_immutable()

                                yield (t1, t2)

        raise StopIteration
    def iter_indefinite_forms(self):
        r"""
        Iterate over indices with non-positive discriminant.
        
        TESTS::
        
            sage: from psage.modform.jacobiforms.jacobiformd1nn_fourierexpansion import *
            sage: list(JacobiFormD1NNFilter(2, 2, reduced = False, weak_forms = True).iter_indefinite_forms())
            [(0, -1), (1, 3), (0, 0), (1, -3), (0, 1), (0, -2), (0, 2)]
            sage: list(JacobiFormD1NNFilter(3, 2, reduced = False, weak_forms = True).iter_indefinite_forms())
            [(0, -1), (1, 3), (2, -4), (0, 0), (2, 4), (1, -3), (0, 1), (0, -2), (0, 2)]
            sage: list(JacobiFormD1NNFilter(10, 2, reduced = True, weak_forms = True).iter_indefinite_forms())
            [(0, 0), (0, 1), (0, 2)]
            sage: list(JacobiFormD1NNFilter(10, 3, reduced = True, weak_forms = True).iter_indefinite_forms())
            [(0, 0), (0, 1), (0, 2), (0, 3)]
            sage: list(JacobiFormD1NNFilter(10, 10, reduced = True, weak_forms = True).iter_indefinite_forms())                                                  
            [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9), (0, 10), (1, 7), (1, 8), (1, 9), (1, 10), (2, 9), (2, 10)]
        """
        B = self.__bound
        m = self.__m
        fm = Integer(4 * self.__m)

        if self.__reduced:
            if self.__weak_forms:
                for n in xrange(0, min(self.__m // 4 + 1, self.__bound)):
                    for r in xrange(
                            isqrt(fm * n - 1) + 1 if n != 0 else 0,
                            self.__m + 1):
                        yield (n, r)
            else:
                for r in xrange(
                        0, min(self.__m + 1,
                               isqrt((self.__bound - 1) * fm) + 1)):
                    if fm.divides(r**2):
                        yield (r**2 // fm, r)
        else:
            if self.__weak_forms:
                ## We first determine the reduced indices.
                for n in xrange(0, min(m // 4 + 1, B)):
                    if n == 0:
                        r_iteration = range(-m + 1, m + 1)
                    else:
                        r_iteration =   range( -m + 1, -isqrt(fm * n - 1) ) \
                                       + range( isqrt(fm * n - 1) + 1, m + 1 )
                    for r in r_iteration:
                        for l in range(
                            (-r - isqrt(r**2 - 4 * m *
                                        (n - (B - 1))) - 1) // (2 * m) + 1,
                            (-r + isqrt(r**2 - 4 * m *
                                        (n - (B - 1)))) // (2 * m) + 1):
                            if n + l * r + m * l**2 >= B:
                                print l, n, r
                            yield (n + l * r + m * l**2, r + 2 * m * l)
            else:
                if self.__bound > 0:
                    yield (0, 0)

                for n in xrange(1, self.__bound):
                    if (fm * n).is_square():
                        rt_fmm = isqrt(fm * n)
                        yield (n, rt_fmm)
                        yield (n, -rt_fmm)

        raise StopIteration
Example #54
0
    def _wronskian_adjoint(self, weight_parity=0, p=None):
        r"""
        The matrix `W^\# \pmod{p}`, mentioned on page 142 of Nils Skoruppa's thesis.
        This matrix is represented by a list of lists of q-expansions.
        
        The q-expansion is shifted by `-(m + 1) (2*m + 1) / 24` in the case of even weights, and it is
        shifted by `-(m - 1) (2*m - 3) / 24` otherwise. This is compensated by the missing q-powers
        returned by _wronskian_invdeterminant.
        
        INPUT:
        
        - `p` -- A prime or ``None``.
        
        - ``weight_parity`` -- An integer (default: `0`).
        """
        try:
            if weight_parity % 2 == 0:
                wronskian_adjoint = self.__wronskian_adjoint_even
            else:
                wronskian_adjoint = self.__wronskian_adjoint_ood

            if p is None:
                return wronskian_adjoint
            else:
                P = PowerSeriesRing(GF(p), 'q')

                return [map(P, row) for row in wronskian_adjoint]

        except AttributeError:
            qexp_prec = self._qexp_precision()

            if p is None:
                PS = self.integral_power_series_ring()
            else:
                PS = PowerSeriesRing(GF(p), 'q')
            m = self.jacobi_index()

            twom = 2 * m
            frmsq = twom**2

            thetas = dict(
                ((i, j), dict()) for i in xrange(m + 1) for j in xrange(m + 1))

            ## We want to calculate \hat \theta_{j,l} = sum_r (2 m r + j)**2l q**(m r**2 + j r)
            ## in the case of even weight, and \hat \theta_{j,l} = sum_r (2 m r + j)**(2l + 1) q**(m r**2 + j r),
            ## otherwise.
            for r in xrange(isqrt((qexp_prec - 1 + m) // m) + 2):
                for j in (xrange(m + 1) if weight_parity %
                          2 == 0 else range(1, m)):
                    fact_p = (twom * r + j)**2
                    fact_m = (twom * r - j)**2
                    if weight_parity % 2 == 0:
                        coeff_p = 2
                        coeff_m = 2
                    else:
                        coeff_p = 2 * (twom * r + j)
                        coeff_m = -2 * (twom * r - j)

                    for l in (xrange(m + 1) if weight_parity %
                              2 == 0 else range(1, m)):
                        thetas[(j, l)][m * r**2 + r * j] = coeff_p
                        thetas[(j, l)][m * r**2 - r * j] = coeff_m
                        coeff_p = coeff_p * fact_p
                        coeff_m = coeff_m * fact_m
            if weight_parity % 2 == 0:
                thetas[(0, 0)][0] = 1

            thetas = dict((k, PS(th).add_bigoh(qexp_prec))
                          for (k, th) in thetas.iteritems())

            W = matrix(PS, m + 1 if weight_parity % 2 == 0 else (m - 1), [
                thetas[(j, l)] for j in (xrange(m + 1) if weight_parity %
                                         2 == 0 else range(1, m))
                for l in (xrange(m + 1) if weight_parity %
                          2 == 0 else range(1, m))
            ])

            ## Since the adjoint of matrices with entries in a general ring
            ## is extremely slow for matrices of small size, we hard code the
            ## the cases `m = 2` and `m = 3`.  The expressions are obtained by
            ## computing the adjoint of a matrix with entries `w_{i,j}` in a
            ## polynomial algebra.
            if W.nrows() == 1:
                Wadj = matrix(PS, [[1]])
            elif W.nrows() == 2:
                Wadj = matrix(PS, [[W[1, 1], -W[0, 1]], [-W[1, 0], W[0, 0]]])

            elif W.nrows() == 3 and qexp_prec > 10**5:
                adj00 = W[1, 1] * W[2, 2] - W[2, 1] * W[1, 2]
                adj01 = -W[1, 0] * W[2, 2] + W[2, 0] * W[1, 2]
                adj02 = W[1, 0] * W[2, 1] - W[2, 0] * W[1, 1]
                adj10 = -W[0, 1] * W[2, 2] + W[2, 1] * W[0, 2]
                adj11 = W[0, 0] * W[2, 2] - W[2, 0] * W[0, 2]
                adj12 = -W[0, 0] * W[2, 1] + W[2, 0] * W[0, 1]
                adj20 = W[0, 1] * W[1, 2] - W[1, 1] * W[0, 2]
                adj21 = -W[0, 0] * W[1, 2] + W[1, 0] * W[0, 2]
                adj22 = W[0, 0] * W[1, 1] - W[1, 0] * W[0, 1]

                Wadj = matrix(PS,
                              [[adj00, adj01, adj02], [adj10, adj11, adj12],
                               [adj20, adj21, adj22]])

            elif W.nrows() == 4 and qexp_prec > 10**5:
                adj00 = -W[0, 2] * W[1, 1] * W[2, 0] + W[0, 1] * W[1, 2] * W[
                    2, 0] + W[0, 2] * W[1, 0] * W[2, 1] - W[0, 0] * W[
                        1, 2] * W[2, 1] - W[0, 1] * W[1, 0] * W[2, 2] + W[
                            0, 0] * W[1, 1] * W[2, 2]
                adj01 = -W[0, 3] * W[1, 1] * W[2, 0] + W[0, 1] * W[1, 3] * W[
                    2, 0] + W[0, 3] * W[1, 0] * W[2, 1] - W[0, 0] * W[
                        1, 3] * W[2, 1] - W[0, 1] * W[1, 0] * W[2, 3] + W[
                            0, 0] * W[1, 1] * W[2, 3]
                adj02 = -W[0, 3] * W[1, 2] * W[2, 0] + W[0, 2] * W[1, 3] * W[
                    2, 0] + W[0, 3] * W[1, 0] * W[2, 2] - W[0, 0] * W[
                        1, 3] * W[2, 2] - W[0, 2] * W[1, 0] * W[2, 3] + W[
                            0, 0] * W[1, 2] * W[2, 3]
                adj03 = -W[0, 3] * W[1, 2] * W[2, 1] + W[0, 2] * W[1, 3] * W[
                    2, 1] + W[0, 3] * W[1, 1] * W[2, 2] - W[0, 1] * W[
                        1, 3] * W[2, 2] - W[0, 2] * W[1, 1] * W[2, 3] + W[
                            0, 1] * W[1, 2] * W[2, 3]

                adj10 = -W[0, 2] * W[1, 1] * W[3, 0] + W[0, 1] * W[1, 2] * W[
                    3, 0] + W[0, 2] * W[1, 0] * W[3, 1] - W[0, 0] * W[
                        1, 2] * W[3, 1] - W[0, 1] * W[1, 0] * W[3, 2] + W[
                            0, 0] * W[1, 1] * W[3, 2]
                adj11 = -W[0, 3] * W[1, 1] * W[3, 0] + W[0, 1] * W[1, 3] * W[
                    3, 0] + W[0, 3] * W[1, 0] * W[3, 1] - W[0, 0] * W[
                        1, 3] * W[3, 1] - W[0, 1] * W[1, 0] * W[3, 3] + W[
                            0, 0] * W[1, 1] * W[3, 3]
                adj12 = -W[0, 3] * W[1, 2] * W[3, 0] + W[0, 2] * W[1, 3] * W[
                    3, 0] + W[0, 3] * W[1, 0] * W[3, 2] - W[0, 0] * W[
                        1, 3] * W[3, 2] - W[0, 2] * W[1, 0] * W[3, 3] + W[
                            0, 0] * W[1, 2] * W[3, 3]
                adj13 = -W[0, 3] * W[1, 2] * W[3, 1] + W[0, 2] * W[1, 3] * W[
                    3, 1] + W[0, 3] * W[1, 1] * W[3, 2] - W[0, 1] * W[
                        1, 3] * W[3, 2] - W[0, 2] * W[1, 1] * W[3, 3] + W[
                            0, 1] * W[1, 2] * W[3, 3]

                adj20 = -W[0, 2] * W[2, 1] * W[3, 0] + W[0, 1] * W[2, 2] * W[
                    3, 0] + W[0, 2] * W[2, 0] * W[3, 1] - W[0, 0] * W[
                        2, 2] * W[3, 1] - W[0, 1] * W[2, 0] * W[3, 2] + W[
                            0, 0] * W[2, 1] * W[3, 2]
                adj21 = -W[0, 3] * W[2, 1] * W[3, 0] + W[0, 1] * W[2, 3] * W[
                    3, 0] + W[0, 3] * W[2, 0] * W[3, 1] - W[0, 0] * W[
                        2, 3] * W[3, 1] - W[0, 1] * W[2, 0] * W[3, 3] + W[
                            0, 0] * W[2, 1] * W[3, 3]
                adj22 = -W[0, 3] * W[2, 2] * W[3, 0] + W[0, 2] * W[2, 3] * W[
                    3, 0] + W[0, 3] * W[2, 0] * W[3, 2] - W[0, 0] * W[
                        2, 3] * W[3, 2] - W[0, 2] * W[2, 0] * W[3, 3] + W[
                            0, 0] * W[2, 2] * W[3, 3]
                adj23 = -W[0, 3] * W[2, 2] * W[3, 1] + W[0, 2] * W[2, 3] * W[
                    3, 1] + W[0, 3] * W[2, 1] * W[3, 2] - W[0, 1] * W[
                        2, 3] * W[3, 2] - W[0, 2] * W[2, 1] * W[3, 3] + W[
                            0, 1] * W[2, 2] * W[3, 3]

                adj30 = -W[1, 2] * W[2, 1] * W[3, 0] + W[1, 1] * W[2, 2] * W[
                    3, 0] + W[1, 2] * W[2, 0] * W[3, 1] - W[1, 0] * W[
                        2, 2] * W[3, 1] - W[1, 1] * W[2, 0] * W[3, 2] + W[
                            1, 0] * W[2, 1] * W[3, 2]
                adj31 = -W[1, 3] * W[2, 1] * W[3, 0] + W[1, 1] * W[2, 3] * W[
                    3, 0] + W[1, 3] * W[2, 0] * W[3, 1] - W[1, 0] * W[
                        2, 3] * W[3, 1] - W[1, 1] * W[2, 0] * W[3, 3] + W[
                            1, 0] * W[2, 1] * W[3, 3]
                adj32 = -W[1, 3] * W[2, 2] * W[3, 0] + W[1, 2] * W[2, 3] * W[
                    3, 0] + W[1, 3] * W[2, 0] * W[3, 2] - W[1, 0] * W[
                        2, 3] * W[3, 2] - W[1, 2] * W[2, 0] * W[3, 3] + W[
                            1, 0] * W[2, 2] * W[3, 3]
                adj33 = -W[1, 3] * W[2, 2] * W[3, 1] + W[1, 2] * W[2, 3] * W[
                    3, 1] + W[1, 3] * W[2, 1] * W[3, 2] - W[1, 1] * W[
                        2, 3] * W[3, 2] - W[1, 2] * W[2, 1] * W[3, 3] + W[
                            1, 1] * W[2, 2] * W[3, 3]

                Wadj = matrix(PS, [[adj00, adj01, adj02, adj03],
                                   [adj10, adj11, adj12, adj13],
                                   [adj20, adj21, adj22, adj23],
                                   [adj30, adj31, adj32, adj33]])
            else:
                Wadj = W.adjoint()

            if weight_parity % 2 == 0:
                wronskian_adjoint = [[Wadj[i, r] for i in xrange(m + 1)]
                                     for r in xrange(m + 1)]
            else:
                wronskian_adjoint = [[Wadj[i, r] for i in xrange(m - 1)]
                                     for r in xrange(m - 1)]

            if p is None:
                if weight_parity % 2 == 0:
                    self.__wronskian_adjoint_even = wronskian_adjoint
                else:
                    self.__wronskian_adjoint_odd = wronskian_adjoint

            return wronskian_adjoint