Example #1
0
    def embedding(self, m, n=None, prec=6, format='embed'):
        """
        Return the value of the ``m``th embedding on a specified input.
        Should only be used when all of the entries in this column are either real
        or imaginary.

        INPUT:

        - ``m`` -- an integer, specifying which embedding to use.
        - ``n`` -- a positive integer, specifying which a_n.  If None, returns the image of
            the generator of the field (i.e. the root corresponding to this embedding).
        - ``prec`` -- the precision to display floating point values
        - ``format`` -- either ``embed`` or ``analytic_embed``.  In the second case, divide by n^((k-1)/2).
        """
        if n is None:
            x = self.cc_data[m].get('embedding_root_real', None)
            y = self.cc_data[m].get('embedding_root_imag', None)
            if x is None or y is None:
                return '?' # we should never see this if we have an exact qexp
        else:
            x, y = self.cc_data[m]['an'][n]
            if format == 'analytic_embed':
                x *= self.analytic_shift[n]
                y *= self.analytic_shift[n]
        if self.cc_data[m]['real']:
            return display_float(x, prec)
        else:
            return display_complex(x, y, prec)
Example #2
0
def specialValueTriple(L, s, sLatex_analytic, sLatex_arithmetic):
    ''' Returns [L_arithmetic, L_analytic, L_val]
        Currently only used for genus 2 curves
        and Dirichlet characters.
        Eventually want to use for all L-functions.
    '''
    number_of_decimals = 10
    val = None
    if L.fromDB:  #getattr(L, 'fromDB', False):
        s_alg = s + L.analytic_normalization
        for x in L.values:
            # the numbers here are always half integers
            # so this comparison is exact
            if x[0] == s_alg:
                val = x[1]
                break
    if val is None:
        if L.fromDB:
            val = "not computed"
        else:
            val = L.sageLfunction.value(s)
            logger.warning(
                "a value of an L-function has been computed on the fly")

    if sLatex_arithmetic:
        lfunction_value_tex_arithmetic = L.texname_arithmetic.replace(
            's)', sLatex_arithmetic + ')')
    else:
        lfunction_value_tex_arithmetic = ''
    if sLatex_analytic:
        lfunction_value_tex_analytic = L.texname.replace(
            '(s', '(' + sLatex_analytic)
    else:
        lfunction_value_tex_analytic = ''

    if isinstance(val, string_types):
        Lval = val
    else:
        ccval = CDF(val)
        # We must test for NaN first, since it would show as zero otherwise
        # Try "RR(NaN) < float(1e-10)" in sage -- GT
        if ccval.real().is_NaN():
            Lval = r"$\infty$"
        else:
            Lval = display_complex(ccval.real(), ccval.imag(),
                                   number_of_decimals)

    return [lfunction_value_tex_analytic, lfunction_value_tex_arithmetic, Lval]
Example #3
0
    def satake(self, m, p, i, prec=6, format='satake'):
        """
        Return a Satake parameter.

        INPUT:

        - ``m`` -- an integer, specifying which embedding to use.
        - ``p`` -- a prime, specifying which a_p.
        - ``i`` -- either 0 or 1, indicating which root of the quadratic.
        - ``prec`` -- the precision to display floating point values
        - ``format`` -- either ``satake`` or ``satake_angle``.  In the second case, give the argument of the Satake parameter
        """
        if format == 'satake':
            alpha = self._get_alpha(m, p, i)
            return display_complex(alpha.real(), alpha.imag(), prec)
        else:
            return self.satake_angle(m, p, i, prec)
Example #4
0
def specialValueTriple(L, s, sLatex_analytic, sLatex_arithmetic):
    ''' Returns [L_arithmetic, L_analytic, L_val]
        Currently only used for genus 2 curves
        and Dirichlet characters.
        Eventually want to use for all L-functions.
    '''
    number_of_decimals = 10
    val = None
    if L.fromDB: #getattr(L, 'fromDB', False):
        s_alg = s + L.analytic_normalization
        for x in L.values:
            # the numbers here are always half integers
            # so this comparison is exact
            if x[0] == s_alg:
                val = x[1]
                break
    if val is None:
        if L.fromDB:
            val = "not computed"
        else:
            val = L.sageLfunction.value(s)
            logger.warning("a value of an L-function has been computed on the fly")

    if sLatex_arithmetic:
        lfunction_value_tex_arithmetic = L.texname_arithmetic.replace('s)',  sLatex_arithmetic + ')')
    else:
        lfunction_value_tex_arithmetic = ''
    if sLatex_analytic:
        lfunction_value_tex_analytic = L.texname.replace('(s', '(' + sLatex_analytic)
    else:
        lfunction_value_tex_analytic = ''

    if isinstance(val, basestring):
        Lval = val
    else:
        ccval = CDF(val)
        # We must test for NaN first, since it would show as zero otherwise
        # Try "RR(NaN) < float(1e-10)" in sage -- GT
        if ccval.real().is_NaN():
            Lval = "$\\infty$"
        else:
            Lval = display_complex(ccval.real(), ccval.imag(), number_of_decimals)

    return [lfunction_value_tex_analytic, lfunction_value_tex_arithmetic, Lval]
Example #5
0
def pretty_coeff(c, prec=9):
    '''
    Format the complex coefficient `c` for display on the website.
    '''
    if isinstance(c, complex):
        x = c.real
        y = c.imag
    else:
        x = real_part(c)
        y = imag_part(c)
    # the number of digits to display 'prec' digits after the .
    digits = lambda z: len(str(abs(z)).split('.')[0].lstrip('0')) + prec

    res = display_complex(x, y, digits=max(map(digits, [x, y])))

    if res == '0':
        return '&nbsp;0'
    else:
        return res
Example #6
0
def pretty_coeff(c, prec=9):
    '''
    Format the complex coefficient `c` for display on the website.
    '''
    if isinstance(c, complex):
        x = c.real
        y = c.imag
    else:
        x = real_part(c)
        y = imag_part(c)
    # the number of digits to display 'prec' digits after the .
    digits = lambda z: len(str(abs(z)).split('.')[0].lstrip('0')) + prec

    res =  display_complex(x, y, digits = max(map(digits, [x, y])))

    if res == '0':
        return '&nbsp;0'
    else:
        return res
Example #7
0
 def q_expansion_cc(self, prec_max):
     eigseq = self.cc_data[self.embedding_m]['an_normalized']
     prec = min(max(eigseq.keys()) + 1, prec_max)
     if prec == 0:
         return 'O(1)'
     s = '\(q\)'
     for j in range(2, prec):
         term = eigseq[j]
         latexterm = display_complex(term[0]*self.analytic_shift[j], term[1]*self.analytic_shift[j], 6, method = "round", parenthesis = True, try_halfinteger=False)
         if latexterm != '0':
             if latexterm == '1':
                 latexterm = ''
             elif latexterm == '-1':
                 latexterm = '-'
             latexterm += ' q^{%d}' % j
             if s != '' and latexterm[0] != '-':
                 latexterm = '+' + latexterm
             s += '\(' + latexterm + '\) '
     # Work around bug in Sage's latex
     s = s.replace('betaq', 'beta q')
     return s + '\(+O(q^{%d})\)' % prec
Example #8
0
def lfuncFEtex(L, fmt):
    """ Returns the LaTex for displaying the Functional equation of the L-function L.
        fmt could be any of the values: "analytic", "selberg"
    """
    if fmt == "arithmetic":
        mu_list = [mu - L.motivic_weight/2 for mu in L.mu_fe]
        nu_list = [nu - L.motivic_weight/2 for nu in L.nu_fe]
        mu_list.sort()
        nu_list.sort()
        texname = L.texname_arithmetic
        try:
            tex_name_s = L.texnamecompleteds_arithmetic
            tex_name_1ms = L.texnamecompleted1ms_arithmetic
        except AttributeError:
            tex_name_s = L.texnamecompleteds
            tex_name_1ms = L.texnamecompleted1ms

    else:
        mu_list = L.mu_fe[:]
        nu_list = L.nu_fe[:]
        texname = L.texname
        tex_name_s = L.texnamecompleteds
        tex_name_1ms = L.texnamecompleted1ms
    ans = ""
    if fmt == "arithmetic" or fmt == "analytic":
        ans = "\\begin{align}\n" + tex_name_s + "=\\mathstrut &"
        if L.level > 1:
            if L.level >= 10**8 and not is_prime(int(L.level)):
                ans += r"\left(%s\right)^{s/2}" % latex(L.level_factored)
            else:
                ans += latex(L.level) + "^{s/2}"
            ans += " \\, "
        def munu_str(factors_list, field):
            assert field in ['\R','\C']
            # set up to accommodate multiplicity of Gamma factors
            old = ""
            res = ""
            curr_exp = 0
            for elt in factors_list:
                if elt == old:
                    curr_exp += 1
                else:
                    old = elt
                    if curr_exp > 1:
                        res += "^{" + str(curr_exp) + "}"
                    if curr_exp > 0:
                        res += " \\, "
                    curr_exp = 1
                    res += "\Gamma_{" + field + "}(s" + seriescoeff(elt, 0, "signed", "", 3) + ")"
            if curr_exp > 1:
                res += "^{" + str(curr_exp) + "}"
            if res != "":
                res +=  " \\, "
            return res
        ans += munu_str(mu_list, '\R')
        ans += munu_str(nu_list, '\C')
        ans += texname + "\\cr\n"
        ans += "=\\mathstrut & "
        if L.sign == 0:
            ans += "\epsilon \cdot "
        else:
            ans += seriescoeff(L.sign, 0, "factor", "", 3) + "\\,"
        ans += tex_name_1ms
        if L.sign == 0 and L.degree == 1:
            ans += "\quad (\\text{with }\epsilon \\text{ not computed})"
        if L.sign == 0 and L.degree > 1:
            ans += "\quad (\\text{with }\epsilon \\text{ unknown})"
        ans += "\n\\end{align}\n"
    elif fmt == "selberg":
        ans += "(" + str(int(L.degree)) + ",\\ "
        if L.level >= 10**8 and not is_prime(int(L.level)):
            ans += latex(L.level_factored)
        else:
            ans += str(int(L.level))
        ans += ",\\ "
        ans += "("
        # this is mostly a hack for GL2 Maass forms
        def real_digits(x):
            return len(str(x).replace('.','').lstrip('-').lstrip('0'))
        def mu_fe_prec(x):
            if L._Ltype == 'maass':
                return real_digits(imag_part(x))
            else:
                return 3
        if L.mu_fe != []:
            mus = [ display_complex(CDF(mu).real(), CDF(mu).imag(),  mu_fe_prec(mu), method="round" ) for mu in L.mu_fe ]
            if len(mus) >= 6 and mus == [mus[0]]*len(mus):
                ans += '[%s]^{%d}' % (mus[0], len(mus))
            else:
                ans += ", ".join(mus)
        else:
            ans += "\\ "
        ans += ":"
        if L.nu_fe != []:
            if len(L.nu_fe) >= 6 and L.nu_fe == [L.nu_fe[0]]*len(L.nu_fe):
                ans += '[%s]^{%d}' % (L.nu_fe[0], len(L.nu_fe))
            else:
                ans += ", ".join(map(str, L.nu_fe))
        else:
            ans += "\\ "
        ans += "),\\ "
        ans += seriescoeff(L.sign, 0, "literal", "", 3)
        ans += ")"

    return(ans)
Example #9
0
def seriescoeff(coeff, index, seriescoefftype, seriestype, digits):
    # seriescoefftype can be: series, serieshtml, signed, literal, factor
    try:
        if isinstance(coeff,str) or isinstance(coeff,unicode):
            if coeff == "I":
                rp = 0
                ip = 1
            elif coeff == "-I":
                rp = 0
                ip = -1
            else:
                coeff = string2number(coeff)
        if type(coeff) == complex:
            rp = coeff.real
            ip = coeff.imag
        else:
            rp = real_part(coeff)
            ip = imag_part(coeff)
    except TypeError:     # mostly a hack for Dirichlet L-functions
        if seriescoefftype == "serieshtml":
            return " +" + coeff + "&middot;" + seriesvar(index, seriestype)
        else:
            return coeff
    ans = ""
    if seriescoefftype in ["series", "serieshtml", "signed", "factor"]:
        parenthesis = True
    else:
        parenthesis = False
    coeff_display =  display_complex(rp, ip, digits, method="truncate", parenthesis=parenthesis)

    # deal with the zero case
    if coeff_display == "0":
        if seriescoefftype=="literal":
            return "0"
        else:
            return ""

    if seriescoefftype=="literal":
        return coeff_display

    if seriescoefftype == "factor":
        if coeff_display == "1":
            return ""
        elif coeff_display == "-1":
            return "-"

    #add signs and fix spacing
    if seriescoefftype in ["series", "serieshtml"]:
        if coeff_display == "1":
            coeff_display = " + "
        elif coeff_display == "-1":
            coeff_display = " - "
        # purely real or complex number that starts with -
        elif coeff_display[0] == '-':
            # add spacings around the minus
            coeff_display = coeff_display.replace('-',' - ')
        else:
            ans += " + "
    elif seriescoefftype == 'signed' and coeff_display[0] != '-':
        # add the plus without the spaces
        ans += "+"

    ans += coeff_display


    if seriescoefftype == "serieshtml":
        ans = ans.replace('i',"<em>i</em>").replace('-',"&minus;")
        if coeff_display[-1] not in [')', ' ']:
            ans += "&middot;"
    if seriescoefftype in ["series", "serieshtml", "signed"]:
        ans += seriesvar(index, seriestype)

    return ans
Example #10
0
def seriescoeff(coeff, index, seriescoefftype, seriestype, digits):
    # seriescoefftype can be: series, serieshtml, signed, literal, factor
    try:
        if isinstance(coeff, string_types):
            if coeff == "I":
                rp = 0
                ip = 1
                coeff = CDF(I)
            elif coeff == "-I":
                rp = 0
                ip = -1
                coeff = CDF(-I)
            else:
                coeff = string2number(coeff)
        if type(coeff) == complex:
            rp = coeff.real
            ip = coeff.imag
        else:
            rp = real_part(coeff)
            ip = imag_part(coeff)
    except TypeError:     # mostly a hack for Dirichlet L-functions
        if seriescoefftype == "serieshtml":
            return " +" + coeff + "&middot;" + seriesvar(index, seriestype)
        else:
            return coeff
    ans = ""
    if seriescoefftype in ["series", "serieshtml", "signed", "factor"]:
        parenthesis = True
    else:
        parenthesis = False
    coeff_display =  display_complex(rp, ip, digits, method="truncate", parenthesis=parenthesis)

    # deal with the zero case
    if coeff_display == "0":
        if seriescoefftype=="literal":
            return "0"
        else:
            return ""

    if seriescoefftype=="literal":
        return coeff_display

    if seriescoefftype == "factor":
        if coeff_display == "1":
            return ""
        elif coeff_display == "-1":
            return "-"

    #add signs and fix spacing
    if seriescoefftype in ["series", "serieshtml"]:
        if coeff_display == "1":
            coeff_display = " + "
        elif coeff_display == "-1":
            coeff_display = " - "
        # purely real or complex number that starts with -
        elif coeff_display[0] == '-':
            # add spacings around the minus
            coeff_display = coeff_display.replace('-',' - ')
        else:
            ans += " + "
    elif seriescoefftype == 'signed' and coeff_display[0] != '-':
        # add the plus without the spaces
        ans += "+"

    ans += coeff_display


    if seriescoefftype == "serieshtml":
        ans = ans.replace('i',"<em>i</em>").replace('-',"&minus;")
        if coeff_display[-1] not in [')', ' ']:
            ans += "&middot;"
    if seriescoefftype in ["series", "serieshtml", "signed"]:
        ans += seriesvar(index, seriestype)

    return ans
Example #11
0
def lfuncFEtex(L, fmt):
    """ Returns the LaTex for displaying the Functional equation of the L-function L.
        fmt could be any of the values: "analytic", "selberg"
    """
    if fmt == "arithmetic":
        mu_list = [mu - L.motivic_weight/2 for mu in L.mu_fe]
        nu_list = [nu - L.motivic_weight/2 for nu in L.nu_fe]
        mu_list.sort()
        nu_list.sort()
        texname = L.texname_arithmetic
        try:
            tex_name_s = L.texnamecompleteds_arithmetic
            tex_name_1ms = L.texnamecompleted1ms_arithmetic
        except AttributeError:
            tex_name_s = L.texnamecompleteds
            tex_name_1ms = L.texnamecompleted1ms

    else:
        mu_list = L.mu_fe[:]
        nu_list = L.nu_fe[:]
        texname = L.texname
        tex_name_s = L.texnamecompleteds
        tex_name_1ms = L.texnamecompleted1ms
    ans = ""
    if fmt == "arithmetic" or fmt == "analytic":
        ans = r"\begin{aligned}" + "\n" + tex_name_s + r"=\mathstrut &"
        if L.level > 1:
            if L.level >= 10**8 and not is_prime(int(L.level)):
                ans += r"\left(%s\right)^{s/2}" % latex(L.level_factored)
            else:
                ans += latex(L.level) + "^{s/2}"
            ans += r" \, "
        def munu_str(factors_list, field):
            assert field in [r'\R',r'\C']
            # set up to accommodate multiplicity of Gamma factors
            old = ""
            res = ""
            curr_exp = 0
            for elt in factors_list:
                if elt == old:
                    curr_exp += 1
                else:
                    old = elt
                    if curr_exp > 1:
                        res += "^{" + str(curr_exp) + "}"
                    if curr_exp > 0:
                        res += r" \, "
                    curr_exp = 1
                    res += r"\Gamma_{" + field + "}(s" + seriescoeff(elt, 0, "signed", "", 3) + ")"
            if curr_exp > 1:
                res += "^{" + str(curr_exp) + "}"
            if res != "":
                res +=  r" \, "
            return res
        ans += munu_str(mu_list, r'\R')
        ans += munu_str(nu_list, r'\C')
        ans += texname + r"\cr" + "\n"
        ans += r"=\mathstrut & "
        if L.sign == 0:
            ans += r"\epsilon \cdot "
        else:
            ans += seriescoeff(L.sign, 0, "factor", "", 3) + r"\,"
        ans += tex_name_1ms
        if L.sign == 0 and L.degree == 1:
            ans += r"\quad (\text{with }\epsilon \text{ not computed})"
        if L.sign == 0 and L.degree > 1:
            ans += r"\quad (\text{with }\epsilon \text{ unknown})"
        ans += "\n" + r"\end{aligned}\n"
    elif fmt == "selberg":
        ans += "(" + str(int(L.degree)) + r",\ "
        if L.level >= 10**8 and not is_prime(int(L.level)):
            ans += latex(L.level_factored)
        else:
            ans += str(int(L.level))
        ans += r",\ "
        ans += "("
        # this is mostly a hack for GL2 Maass forms
        def real_digits(x):
            return len(str(x).replace('.','').lstrip('-').lstrip('0'))
        def mu_fe_prec(x):
            if L._Ltype == 'maass':
                return real_digits(imag_part(x))
            else:
                return 3
        if L.mu_fe != []:
            mus = [ display_complex(CDF(mu).real(), CDF(mu).imag(),  mu_fe_prec(mu), method="round" ) for mu in L.mu_fe ]
            if len(mus) >= 6 and mus == [mus[0]]*len(mus):
                ans += '[%s]^{%d}' % (mus[0], len(mus))
            else:
                ans += ", ".join(mus)
        else:
            ans += r"\ "
        ans += ":"
        if L.nu_fe != []:
            if len(L.nu_fe) >= 6 and L.nu_fe == [L.nu_fe[0]]*len(L.nu_fe):
                ans += '[%s]^{%d}' % (L.nu_fe[0], len(L.nu_fe))
            else:
                ans += ", ".join(map(str, L.nu_fe))
        else:
            ans += r"\ "
        ans += r"),\ "
        ans += seriescoeff(L.sign, 0, "literal", "", 3)
        ans += ")"

    return(ans)
Example #12
0
    def setup_cc_data(self, info):
        """
        INPUT:

        - ``info`` -- a dictionary with keys
          - ``m`` -- a string describing the embedding indexes desired
          - ``n`` -- a string describing the a_n desired
          - ``CC_m`` -- a list of embedding indexes
          - ``CC_n`` -- a list of desired a_n
          - ``format`` -- one of 'embed', 'analytic_embed', 'satake', or 'satake_angle'
        """
        an_formats = ['embed','analytic_embed', None]
        angles_formats = ['satake','satake_angle', None]
        analytic_shift_formats = ['embed', None]
        cc_proj = ['conrey_index','embedding_index','embedding_m','embedding_root_real','embedding_root_imag']
        format = info.get('format')
        query = {'hecke_orbit_code':self.hecke_orbit_code}


        # deal with m
        if self.embedding_label is None:
            m = info.get('m','1-%s'%(min(self.dim,20)))
            if '.' in m:
                m = re.sub(r'\d+\.\d+', self.embedding_from_embedding_label, m)
            CC_m = info['CC_m'] if 'CC_m' in info else integer_options(m)
            CC_m = sorted(set(CC_m))
            # if it is a range
            if len(CC_m) - 1 == CC_m[-1] - CC_m[0]:
                query['embedding_m'] = {'$gte':CC_m[0], '$lte':CC_m[-1]}
            else:
                query['embedding_m'] = {'$in': CC_m}
            self.embedding_m = None
        else:
            self.embedding_m = int(info['CC_m'][0])
            cc_proj.extend(['dual_conrey_index', 'dual_embedding_index'])
            query = {'label' : self.label + '.' + self.embedding_label}

        if format is None and 'CC_n' not in info:
            # for download
            CC_n = (1, self.an_cc_bound)
        else:
            n = info.get('n','1-10')
            CC_n = info['CC_n'] if 'CC_n' in info else integer_options(n)
            # convert CC_n to an interval in [1,an_bound]
            CC_n = ( max(1, min(CC_n)), min(self.an_cc_bound, max(CC_n)) )
        an_keys = (CC_n[0]-1, CC_n[1])
        # extra 5 primes in case we hit too many bad primes
        angles_keys = (
                bisect.bisect_left(primes_for_angles, CC_n[0]),
                min(bisect.bisect_right(primes_for_angles, CC_n[1]) + 5,
                    self.primes_cc_bound)
                )
        an_projection = 'an_normalized[%d:%d]' % an_keys
        angles_projection = 'angles[%d:%d]' % angles_keys
        if format in an_formats:
            cc_proj.append(an_projection)
        if format in angles_formats:
            cc_proj.append(angles_projection)

        cc_data= list(db.mf_hecke_cc.search(query, projection = cc_proj))
        if not cc_data:
            self.has_complex_qexp = False
        else:
            self.has_complex_qexp = True
            self.cc_data = {}
            for embedded_mf in cc_data:
                if format in an_formats:
                    an_normalized = embedded_mf.pop(an_projection)
                    # we don't store a_0, thus the +1
                    embedded_mf['an_normalized'] = {i: [float(x), float(y)] for i, (x, y) in enumerate(an_normalized, an_keys[0] + 1)}
                if format in angles_formats:
                    embedded_mf['angles'] = {primes_for_angles[i]: theta for i, theta in enumerate(embedded_mf.pop(angles_projection), angles_keys[0])}
                self.cc_data[embedded_mf.pop('embedding_m')] = embedded_mf
            if format in analytic_shift_formats:
                self.analytic_shift = {i : RR(i)**((ZZ(self.weight)-1)/2) for i in self.cc_data.values()[0]['an_normalized'].keys()}
            if format in angles_formats:
                self.character_values = defaultdict(list)
                G = DirichletGroup_conrey(self.level)
                chars = [DirichletCharacter_conrey(G, char) for char in self.conrey_indexes]
                for p in self.cc_data.values()[0]['angles'].keys():
                    if p.divides(self.level):
                        self.character_values[p] = None
                        continue
                    for chi in chars:
                        c = chi.logvalue(p) * self.char_order
                        angle = float(c / self.char_order)
                        value = CDF(0,2*CDF.pi()*angle).exp()
                        self.character_values[p].append((angle, value))

        if self.embedding_m is not None:
            m = self.embedding_m
            dci = self.cc_data[m].get('dual_conrey_index')
            dei = self.cc_data[m].get('dual_embedding_index')
            self.dual_label = "%s.%s" % (dci, dei)
            x = self.cc_data[m].get('embedding_root_real')
            y = self.cc_data[m].get('embedding_root_imag')
            if x is None or y is None:
                self.embedding_root = None
            else:
                self.embedding_root = display_complex(x, y, 6, method='round', try_halfinteger=False)