mirror of
https://github.com/vale981/arb
synced 2025-03-05 09:21:38 -05:00
split doc also
This commit is contained in:
parent
55450bb62c
commit
0428ebf806
4 changed files with 388 additions and 372 deletions
|
@ -6,8 +6,10 @@
|
|||
*Warning: the interfaces in this module are experimental and may change
|
||||
without notice.*
|
||||
|
||||
This module allows working with Dirichlet characters, Dirichlet L-functions,
|
||||
and related functions.
|
||||
This module allows working with values of Dirichlet characters, Dirichlet L-functions,
|
||||
and related functions. Working with Dirichlet characters is documented in
|
||||
:ref:`dirichlet`.
|
||||
|
||||
A Dirichlet L-function is the analytic continuation of an L-series
|
||||
|
||||
.. math ::
|
||||
|
@ -20,309 +22,17 @@ The code in other modules for computing the Riemann zeta function,
|
|||
Hurwitz zeta function and polylogarithm will possibly be migrated to this
|
||||
module in the future.
|
||||
|
||||
Multiplicative group modulo *q*
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Working with Dirichlet characters mod *q* consists mainly
|
||||
in going from residue classes mod *q* to exponents on a set
|
||||
of generators of the group.
|
||||
|
||||
This implementation relies on the Conrey numbering scheme
|
||||
introduced in the LMFDB, which is an explicit choice of isomorphism
|
||||
|
||||
.. math::
|
||||
|
||||
(\mathbb Z/q\mathbb Z)^\times & \to &\bigoplus_i \mathbb Z/\phi_i\mathbb Z \\
|
||||
x & \mapsto & (e_i)
|
||||
|
||||
We call *number* a residue class `x` modulo *q*, and *log* the
|
||||
corresponding vector `(e_i)` of exponents of Conrey generators.
|
||||
|
||||
Going from a *log* to the corresponding *number* is a cheap
|
||||
operation called exp, while the converse requires computing discrete
|
||||
logarithms.
|
||||
|
||||
.. type:: acb_dirichlet_group_struct
|
||||
|
||||
.. type:: acb_dirichlet_group_t
|
||||
|
||||
Represents the group of Dirichlet characters mod *q*.
|
||||
|
||||
An *acb_dirichlet_group_t* is defined as an array of *acb_dirichlet_group_struct*
|
||||
of length 1, permitting it to be passed by reference.
|
||||
|
||||
.. function:: void acb_dirichlet_group_init(acb_dirichlet_group_t G, ulong q)
|
||||
|
||||
Initializes *G* to the group of Dirichlet characters mod *q*.
|
||||
|
||||
This method computes a canonical decomposition of *G* in terms of cyclic
|
||||
groups, which are the mod `p^e` subgroups for `p^e\|q`.
|
||||
In particular *G* contains:
|
||||
|
||||
- the number *num* of components
|
||||
|
||||
- the generators
|
||||
|
||||
- the exponent *expo* of the group
|
||||
|
||||
It does *not* automatically precompute lookup tables
|
||||
of discrete logarithms or numerical roots of unity, and can therefore
|
||||
safely be called even with large *q*.
|
||||
|
||||
For implementation reasons, the largest prime factor of *q* must not
|
||||
exceed `10^{12}` (an abort will be raised). This restriction could
|
||||
be removed in the future.
|
||||
|
||||
.. function:: void acb_dirichlet_subgroup_init(acb_dirichlet_group_t H, const acb_dirichlet_group_t G, ulong h)
|
||||
|
||||
Given an already computed group *G* mod `q`, initialize its subgroup *H*
|
||||
defined mod `h\mid q`. Precomputed discrete log tables are inherited.
|
||||
|
||||
.. function:: void acb_dirichlet_group_clear(acb_dirichlet_group_t G)
|
||||
|
||||
Clears *G*. Remark this function does *not* clear the discrete logarithm
|
||||
tables stored in *G* (which may be shared with another group).
|
||||
|
||||
.. function:: void acb_dirichlet_group_dlog_precompute(acb_dirichlet_group_t G, ulong num)
|
||||
|
||||
Precompute decomposition and tables for discrete log computations in *G*,
|
||||
so as to minimize the complexity of *num* calls to discrete logarithms.
|
||||
|
||||
If *num* gets very large, the entire group may be indexed.
|
||||
|
||||
.. function:: void acb_dirichlet_group_dlog_clear(acb_dirichlet_group_t G, ulong num)
|
||||
|
||||
Clear discrete logarithm tables in *G*. When discrete logarithm tables are
|
||||
shared with subgroups, those subgroups must be cleared before clearing the
|
||||
tables.
|
||||
|
||||
Conrey elements
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. type:: acb_dirichlet_conrey_struct
|
||||
|
||||
.. type:: acb_dirichlet_conrey_t
|
||||
|
||||
Represents elements of the unit group mod *q*, keeping both the
|
||||
*number* (residue class) and *log* (exponents on the group
|
||||
generators).
|
||||
|
||||
.. function:: void acb_dirichlet_conrey_log(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G, ulong m)
|
||||
|
||||
Sets *x* to the element of number *m*, computing its log using discrete
|
||||
logarithm in *G*.
|
||||
|
||||
.. function:: ulong acb_dirichlet_conrey_exp(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G)
|
||||
|
||||
Compute the reverse operation.
|
||||
|
||||
.. function:: void acb_dirichlet_conrey_one(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G)
|
||||
|
||||
Sets *x* to the *number* `1\in G`, having *log* `[0,\dots 0]`.
|
||||
|
||||
.. function:: void acb_dirichlet_conrey_first_primitive(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G)
|
||||
|
||||
Sets *x* to the first primitive element of *G*, having *log* `[1,\dots 1]`,
|
||||
or `[0, 1, \dots 1]` if `8\mid q`.
|
||||
|
||||
.. function:: void acb_dirichlet_conrey_set(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t y)
|
||||
|
||||
Sets *x* to the element *y*.
|
||||
|
||||
.. function:: int acb_dirichlet_conrey_next(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G)
|
||||
|
||||
Sets *x* to the next conrey element in *G* with lexicographic ordering.
|
||||
|
||||
The return value
|
||||
is the index of the last updated exponent of *x*, or *-1* if the last
|
||||
element has been reached.
|
||||
|
||||
This function allows to iterate on the elements of *G* looping on their *log*.
|
||||
Note that it produces elements in seemingly random *number* order.
|
||||
|
||||
The following template can be used to loop over all elements *x* in *G*::
|
||||
|
||||
acb_conrey_one(x, G);
|
||||
do {
|
||||
/* use Conrey element x */
|
||||
} while (acb_dirichlet_conrey_next(x, G) >= 0);
|
||||
|
||||
.. function:: int acb_dirichlet_conrey_next_primitive(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G)
|
||||
|
||||
Same as :func:`acb_dirichlet_conrey_next`, but jumps to the next element
|
||||
corresponding to a primitive character of *G*.
|
||||
|
||||
.. function:: ulong acb_dirichlet_index_conrey(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x);
|
||||
|
||||
Returns the lexicographic index of *x* as an integer in `0\dots \varphi(q)`.
|
||||
|
||||
.. function:: void acb_dirichlet_conrey_index(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G, ulong j)
|
||||
|
||||
Sets *x* to the Conrey element of lexicographic index *j*.
|
||||
|
||||
.. function:: int acb_dirichlet_conrey_eq(const acb_dirichlet_conrey_t x, const acb_dirichlet_conrey_t y)
|
||||
|
||||
.. function:: int acb_dirichlet_conrey_eq_deep(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x, const acb_dirichlet_conrey_t y)
|
||||
|
||||
Return 1 if *x* equals *y*.
|
||||
The second version checks every byte of the representation and is intended for testing only.
|
||||
|
||||
Dirichlet characters
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Dirichlet characters take value in a finite cyclic group of roots of unity plus zero.
|
||||
|
||||
When evaluation functions return a *ulong*, this number corresponds to the
|
||||
power of a primitive root of unity, the special value *ACB_DIRICHLET_CHI_NULL*
|
||||
encoding the zero value.
|
||||
|
||||
The Conrey numbering scheme makes explicit the mathematical fact that
|
||||
the group *G* is isomorphic to its dual, so that a character is described by
|
||||
a *number*.
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{array}{ccccc}
|
||||
(\mathbb Z/q\mathbb Z)^\times \times (\mathbb Z/q\mathbb Z)^\times & \to & \bigoplus_i \mathbb Z/\phi_i\mathbb Z \times \mathbb Z/\phi_i\mathbb Z & \to &\mathbb C \\
|
||||
(m,n) & \mapsto& (a_i,b_i) &\mapsto& \chi_q(m,n) = \exp(2i\pi\sum \frac{a_ib_i}{\phi_i} )
|
||||
\end{array}
|
||||
|
||||
.. function:: ulong acb_dirichlet_ui_pairing(const acb_dirichlet_group_t G, ulong m, ulong n)
|
||||
|
||||
.. function:: ulong acb_dirichlet_ui_pairing_conrey(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t a, const acb_dirichlet_conrey_t b)
|
||||
|
||||
Compute the value of the Dirichlet pairing on numbers *m* and *n*, as
|
||||
exponent modulo *G->expo*.
|
||||
The second form takes the Conrey index *a* and *b*, and does not take discrete
|
||||
logarithms.
|
||||
|
||||
The returned value is the numerator of the actual value exponent mod the group exponent *G->expo*.
|
||||
|
||||
Character type
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. type:: acb_dirichlet_char_struct
|
||||
|
||||
.. type:: acb_dirichlet_char_t
|
||||
|
||||
Represents a Dirichlet character. This structure contains various
|
||||
useful invariants such as the order, the parity and the conductor of the character.
|
||||
|
||||
An *acb_dirichlet_char_t* is defined as an array of *acb_dirichlet_char_struct*
|
||||
of length 1, permitting it to be passed by reference.
|
||||
|
||||
.. function:: void acb_dirichlet_char_init(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G)
|
||||
|
||||
Initializes *chi* to an element of the group *G* and sets its value
|
||||
to the principal character.
|
||||
|
||||
.. function:: void acb_dirichlet_char_clear(acb_dirichlet_char_t chi)
|
||||
|
||||
Clears *chi*.
|
||||
|
||||
.. function:: void acb_dirichlet_char(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G, ulong n)
|
||||
|
||||
Sets *chi* to the Dirichlet character of number *n*, using Conrey numbering scheme.
|
||||
This function performs a discrete logarithm in *G*.
|
||||
|
||||
.. function:: void acb_dirichlet_char_conrey(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x)
|
||||
|
||||
Sets *chi* to the Dirichlet character corresponding to *x*.
|
||||
|
||||
.. function:: int acb_dirichlet_char_eq(const acb_dirichlet_char_t chi1, const acb_dirichlet_char_t chi2)
|
||||
|
||||
.. function:: int acb_dirichlet_char_eq_deep(const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi1, const acb_dirichlet_char_t chi2)
|
||||
|
||||
Return 1 if *chi1* equals *chi2*.
|
||||
The second version checks every byte of the representation and is intended for testing only.
|
||||
|
||||
.. function:: acb_dirichlet_char_is_principal(const acb_dirichlet_char_t chi)
|
||||
|
||||
Return 1 if *chi* is the principal character mod *q*.
|
||||
|
||||
.. function:: void acb_dirichlet_char_one(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G)
|
||||
|
||||
Sets *chi* to the principal character.
|
||||
|
||||
.. function:: void acb_dirichlet_char_set(acb_dirichlet_char_t chi1, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi2)
|
||||
|
||||
Sets *chi1* to the character *chi2*.
|
||||
|
||||
.. function:: int acb_dirichlet_char_next(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G)
|
||||
|
||||
Sets *x* to the next character in *G* with lexicographic Conrey ordering
|
||||
(see :func:`acb_dirichlet_conrey_next`). The return value
|
||||
is the index of the last updated exponent of *x*, or *-1* if the last
|
||||
element has been reached.
|
||||
|
||||
.. function:: int acb_dirichlet_char_next_primitive(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G)
|
||||
|
||||
Like :func:`acb_dirichlet_char_next`, but only generates primitive
|
||||
characters.
|
||||
|
||||
Character properties
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
As a consequence of the Conrey numbering, all these numbers are available at the
|
||||
level of *number* and Conrey *log* elements, and for *char*.
|
||||
No discrete log computation is performed.
|
||||
|
||||
.. function:: ulong acb_dirichlet_number_primitive(const acb_dirichlet_group_t G)
|
||||
|
||||
Return the number of primitive elements in *G*.
|
||||
|
||||
.. function:: ulong acb_dirichlet_ui_conductor(const acb_dirichlet_group_t G, ulong a)
|
||||
|
||||
.. function:: ulong acb_dirichlet_conrey_conductor(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x)
|
||||
|
||||
.. function:: ulong acb_dirichlet_char_conductor(const acb_dirichlet_char_t chi)
|
||||
|
||||
Return the *conductor* of `\chi_q(a,\cdot)`, that is the smallest `r` dividing `q`
|
||||
such `\chi_q(a,\cdot)` can be obtained as a character mod `r`.
|
||||
This number is precomputed for the *char* type.
|
||||
|
||||
.. function:: int acb_dirichlet_ui_parity(const acb_dirichlet_group_t G, ulong a)
|
||||
|
||||
.. function:: int acb_dirichlet_conrey_parity(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x)
|
||||
|
||||
.. function:: int acb_dirichlet_char_parity(const acb_dirichlet_char_t chi)
|
||||
|
||||
Return the *parity* `\lambda` in `\{0,1\}` of `\chi_q(a,\cdot)`, such that
|
||||
`\chi_q(a,-1)=(-1)^\lambda`.
|
||||
This number is precomputed for the *char* type.
|
||||
|
||||
.. function:: ulong acb_dirichlet_ui_order(const acb_dirichlet_group_t G, ulong a)
|
||||
|
||||
.. function:: int acb_dirichlet_conrey_order(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x)
|
||||
|
||||
.. function:: ulong acb_dirichlet_char_order(const acb_dirichlet_char_t chi)
|
||||
|
||||
Return the order of `\chi_q(a,\cdot)` which is the order of `a\bmod q`.
|
||||
This number is precomputed for the *char* type.
|
||||
|
||||
.. function:: int acb_dirichlet_char_is_real(const acb_dirichlet_char_t chi)
|
||||
|
||||
Return 1 if *chi* is a real character (iff it has order `\leq 2`).
|
||||
|
||||
Character evaluation
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
The image of a Dirichlet character is a finite cyclic group. Dirichlet
|
||||
character evaluations are either exponents in this group, or an *acb_t* root of
|
||||
unity.
|
||||
|
||||
.. function:: ulong acb_dirichlet_ui_chi_conrey(const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, const acb_dirichlet_conrey_t x)
|
||||
|
||||
.. function:: ulong acb_dirichlet_ui_chi(const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, ulong n)
|
||||
|
||||
Compute that value `\chi(n)` as the exponent mod the order of `\chi`.
|
||||
|
||||
.. function:: void acb_dirichlet_chi(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, ulong n, slong prec)
|
||||
.. function:: void acb_dirichlet_chi(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, ulong n, slong prec)
|
||||
|
||||
Sets *res* to `\chi(n)`, the value of the Dirichlet character *chi*
|
||||
at the integer *n*.
|
||||
|
||||
There are no restrictions on *n*.
|
||||
.. function:: void acb_dirichlet_chi_vec(acb_ptr v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv, slong prec)
|
||||
|
||||
Compute the *nv* first Dirichlet values.
|
||||
|
||||
Roots of unity
|
||||
-------------------------------------------------------------------------------
|
||||
|
@ -356,46 +66,22 @@ Roots of unity
|
|||
|
||||
Sets *z* to `x^n` where *t* contains precomputed powers of `x`.
|
||||
|
||||
Vector evaluation
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. function:: void acb_dirichlet_ui_chi_vec(ulong * v, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong nv)
|
||||
|
||||
Compute the list of exponent values *v[k]* for `0\leq k < nv`.
|
||||
|
||||
.. function:: void acb_dirichlet_chi_vec(acb_ptr v, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong nv, slong prec)
|
||||
|
||||
Compute the *nv* first Dirichlet values.
|
||||
|
||||
Character operations
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. function:: void acb_dirichlet_conrey_mul(acb_dirichlet_conrey_t c, const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t a, const acb_dirichlet_conrey_t b)
|
||||
|
||||
.. function:: void acb_dirichlet_char_mul(acb_dirichlet_char_t chi12, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi1, const acb_dirichlet_char_t chi2)
|
||||
|
||||
Multiply two characters in the same group.
|
||||
|
||||
.. function:: void acb_dirichlet_conrey_pow(acb_dirichlet_conrey_t c, const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t a, ulong n)
|
||||
|
||||
Take the power of some character.
|
||||
|
||||
Gauss and Jacobi sums
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. function:: void acb_dirichlet_gauss_sum_naive(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong prec)
|
||||
.. function:: void acb_dirichlet_gauss_sum_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_gauss_sum_factor(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong prec)
|
||||
.. function:: void acb_dirichlet_gauss_sum_factor(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_gauss_sum_order2(acb_t res, const acb_dirichlet_char_t chi, slong prec)
|
||||
.. function:: void acb_dirichlet_gauss_sum_order2(acb_t res, const dirichlet_char_t chi, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_gauss_sum_theta(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong prec)
|
||||
.. function:: void acb_dirichlet_gauss_sum_theta(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_gauss_sum(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong prec)
|
||||
.. function:: void acb_dirichlet_gauss_sum(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_gauss_sum_ui(acb_t res, const acb_dirichlet_group_t G, ulong a, slong prec)
|
||||
.. function:: void acb_dirichlet_gauss_sum_ui(acb_t res, const dirichlet_group_t G, ulong a, slong prec)
|
||||
|
||||
Compute the Gauss sum
|
||||
Sets *res* to the Gauss sum
|
||||
|
||||
.. math::
|
||||
|
||||
|
@ -419,17 +105,17 @@ Gauss and Jacobi sums
|
|||
|
||||
- the *ui* version only takes the Conrey number *a* as parameter.
|
||||
|
||||
.. function:: void acb_dirichlet_jacobi_sum_naive(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi1, const acb_dirichlet_char_t chi2, slong prec)
|
||||
.. function:: void acb_dirichlet_jacobi_sum_naive(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_jacobi_sum_factor(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi1, const acb_dirichlet_char_t chi2, slong prec)
|
||||
.. function:: void acb_dirichlet_jacobi_sum_factor(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_jacobi_sum_gauss(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi1, const acb_dirichlet_char_t chi2, slong prec)
|
||||
.. function:: void acb_dirichlet_jacobi_sum_gauss(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_jacobi_sum(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi1, const acb_dirichlet_char_t chi2, slong prec)
|
||||
.. function:: void acb_dirichlet_jacobi_sum(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_jacobi_sum_ui(acb_t res, const acb_dirichlet_group_t G, ulong a, ulong b, slong prec)
|
||||
.. function:: void acb_dirichlet_jacobi_sum_ui(acb_t res, const dirichlet_group_t G, ulong a, ulong b, slong prec)
|
||||
|
||||
Compute the Jacobi sum
|
||||
Computes the Jacobi sum
|
||||
|
||||
.. math::
|
||||
|
||||
|
@ -463,9 +149,9 @@ For `\Re(t)>0` we write `x(t)=\exp(-\frac{\pi}{N}t^2)` and define
|
|||
|
||||
\Theta_q(a,t) = \sum_{n\geq 0} \chi_q(a, n) x(t)^{n^2}.
|
||||
|
||||
.. function:: void acb_dirichlet_chi_theta_arb(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, const arb_t t, slong prec)
|
||||
.. function:: void acb_dirichlet_chi_theta_arb(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, const arb_t t, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_ui_theta_arb(acb_t res, const acb_dirichlet_group_t G, ulong a, const arb_t t, slong prec)
|
||||
.. function:: void acb_dirichlet_ui_theta_arb(acb_t res, const dirichlet_group_t G, ulong a, const arb_t t, slong prec)
|
||||
|
||||
Compute the theta series `\Theta_q(a,t)` for real argument `t>0`.
|
||||
Beware that if `t<1` the functional equation
|
||||
|
@ -516,13 +202,13 @@ the Fourier transform on Conrey labels as
|
|||
g(a) = \sum_{b\bmod q}\chi_q(a,b)f(b)
|
||||
|
||||
|
||||
.. function:: void acb_dirichlet_dft_conrey(acb_ptr w, acb_srcptr v, const acb_dirichlet_group_t G, slong prec)
|
||||
.. function:: void acb_dirichlet_dft_conrey(acb_ptr w, acb_srcptr v, const dirichlet_group_t G, slong prec)
|
||||
|
||||
Compute the DFT of *v* using Conrey indices.
|
||||
This function assumes *v* and *w* are vectors
|
||||
of size *G->phi_q*, whose values correspond to a lexicographic ordering
|
||||
of Conrey logs (as obtained using :func:`acb_dirichlet_conrey_next` or
|
||||
by :func:`acb_dirichlet_index_conrey`).
|
||||
of Conrey logs (as obtained using :func:`dirichlet_conrey_next` or
|
||||
by :func:`dirichlet_index_conrey`).
|
||||
|
||||
For example, if `q=15`, the Conrey elements are stored in following
|
||||
order
|
||||
|
@ -542,7 +228,7 @@ the Fourier transform on Conrey labels as
|
|||
9 [1, 4] 11
|
||||
======= ============= =====================
|
||||
|
||||
.. function:: void acb_dirichlet_dft(acb_ptr w, acb_srcptr v, const acb_dirichlet_group_t G, slong prec)
|
||||
.. function:: void acb_dirichlet_dft(acb_ptr w, acb_srcptr v, const dirichlet_group_t G, slong prec)
|
||||
|
||||
Compute the DFT of *v* using Conrey numbers.
|
||||
This function assumes *v* and *w* are vectors of size *G->q*.
|
||||
|
@ -588,21 +274,22 @@ Simple functions
|
|||
L-functions
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. function:: void acb_dirichlet_root_number_theta(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong prec)
|
||||
.. function:: void acb_dirichlet_root_number_theta(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec)
|
||||
|
||||
.. function:: void acb_dirichlet_root_number(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong prec)
|
||||
.. function:: void acb_dirichlet_root_number(acb_t res, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec)
|
||||
|
||||
Sets *res* to the root number `\epsilon(\chi)` for a primitive character *chi*,
|
||||
which appears in the functional equation (where `p` is the parity of `\chi`):
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{q}{π})^{\frac{s+p}2}\Gamma(\frac{s+p}2) L(s, \chi) = \epsilon(\chi) \frac{q}{π})^{\frac{1-s+p}2}\Gamma(\frac{1-s+p}2) L(1 - s, \overline\chi)
|
||||
(\frac{q}{π})^{\frac{s+p}2}\Gamma(\frac{s+p}2) L(s, \chi) = \epsilon(\chi) (\frac{q}{π})^{\frac{1-s+p}2}\Gamma(\frac{1-s+p}2) L(1 - s, \overline\chi)
|
||||
|
||||
The *theta* variant uses the evaluation at `t=1` of the Theta series.
|
||||
The default version computes it via the gauss sum.
|
||||
- The *theta* variant uses the evaluation at `t=1` of the Theta series.
|
||||
|
||||
.. function:: void acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong prec)
|
||||
- The default version computes it via the gauss sum.
|
||||
|
||||
.. function:: void acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec)
|
||||
|
||||
Compute `L(s,\chi)` using decomposition in terms of the Hurwitz zeta function
|
||||
|
||||
|
@ -615,24 +302,9 @@ L-functions
|
|||
|
||||
This formula is slow for large *q*.
|
||||
|
||||
.. function:: void acb_dirichlet_l_vec_hurwitz(acb_ptr res, const acb_t s, const acb_dirichlet_group_t G, slong prec)
|
||||
.. function:: void acb_dirichlet_l_vec_hurwitz(acb_ptr res, const acb_t s, const dirichlet_group_t G, slong prec)
|
||||
|
||||
Compute all values `L(s,\chi)` for `\chi` mod `q`, by Hurwitz formula and
|
||||
discrete Fourier transform.
|
||||
*res* is assumed to have length *G->phi_q* and values are stored by lexicographically ordered
|
||||
Conrey logs. See :func:`acb_dirichlet_dft_conrey`.
|
||||
|
||||
Implementation notes
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
The current implementation introduces a *char* type which contains a *conrey*
|
||||
log plus additional information which
|
||||
|
||||
- makes evaluation of a single character a bit faster
|
||||
|
||||
- has some initialization cost.
|
||||
|
||||
Even if it is straightforward to convert a *conrey* log to the
|
||||
corresponding *char*, looping is faster at the
|
||||
level of Conrey representation. Things can be improved on this aspect
|
||||
but it makes code more intricate.
|
||||
|
|
342
doc/source/dirichlet.rst
Normal file
342
doc/source/dirichlet.rst
Normal file
|
@ -0,0 +1,342 @@
|
|||
.. _dirichlet:
|
||||
|
||||
**dirichlet.h** -- Dirichlet characters
|
||||
===================================================================================
|
||||
|
||||
*Warning: the interfaces in this module are experimental and may change
|
||||
without notice.*
|
||||
|
||||
This module allows working with Dirichlet characters algebraically.
|
||||
For evaluations of characters as complex numbers and Dirichlet L-functions,
|
||||
see the :ref:`acb_dirichlet` module.
|
||||
|
||||
Multiplicative group modulo *q*
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Working with Dirichlet characters mod *q* consists mainly
|
||||
in going from residue classes mod *q* to exponents on a set
|
||||
of generators of the group.
|
||||
|
||||
This implementation relies on the Conrey numbering scheme
|
||||
introduced in the LMFDB, which is an explicit choice of isomorphism
|
||||
|
||||
.. math::
|
||||
|
||||
(\mathbb Z/q\mathbb Z)^\times & \to &\bigoplus_i \mathbb Z/\phi_i\mathbb Z \\
|
||||
x & \mapsto & (e_i)
|
||||
|
||||
We call *number* a residue class `x` modulo *q*, and *log* the
|
||||
corresponding vector `(e_i)` of exponents of Conrey generators.
|
||||
|
||||
Going from a *log* to the corresponding *number* is a cheap
|
||||
operation called exp, while the converse requires computing discrete
|
||||
logarithms.
|
||||
|
||||
.. type:: dirichlet_group_struct
|
||||
|
||||
.. type:: dirichlet_group_t
|
||||
|
||||
Represents the group of Dirichlet characters mod *q*.
|
||||
|
||||
An *dirichlet_group_t* is defined as an array of *dirichlet_group_struct*
|
||||
of length 1, permitting it to be passed by reference.
|
||||
|
||||
.. function:: void dirichlet_group_init(dirichlet_group_t G, ulong q)
|
||||
|
||||
Initializes *G* to the group of Dirichlet characters mod *q*.
|
||||
|
||||
This method computes a canonical decomposition of *G* in terms of cyclic
|
||||
groups, which are the mod `p^e` subgroups for `p^e\|q`.
|
||||
In particular *G* contains:
|
||||
|
||||
- the number *num* of components
|
||||
|
||||
- the generators
|
||||
|
||||
- the exponent *expo* of the group
|
||||
|
||||
It does *not* automatically precompute lookup tables
|
||||
of discrete logarithms or numerical roots of unity, and can therefore
|
||||
safely be called even with large *q*.
|
||||
|
||||
For implementation reasons, the largest prime factor of *q* must not
|
||||
exceed `10^{12}` (an abort will be raised). This restriction could
|
||||
be removed in the future.
|
||||
|
||||
.. function:: void dirichlet_subgroup_init(dirichlet_group_t H, const dirichlet_group_t G, ulong h)
|
||||
|
||||
Given an already computed group *G* mod `q`, initialize its subgroup *H*
|
||||
defined mod `h\mid q`. Precomputed discrete log tables are inherited.
|
||||
|
||||
.. function:: void dirichlet_group_clear(dirichlet_group_t G)
|
||||
|
||||
Clears *G*. Remark this function does *not* clear the discrete logarithm
|
||||
tables stored in *G* (which may be shared with another group).
|
||||
|
||||
.. function:: void dirichlet_group_dlog_precompute(dirichlet_group_t G, ulong num)
|
||||
|
||||
Precompute decomposition and tables for discrete log computations in *G*,
|
||||
so as to minimize the complexity of *num* calls to discrete logarithms.
|
||||
|
||||
If *num* gets very large, the entire group may be indexed.
|
||||
|
||||
.. function:: void dirichlet_group_dlog_clear(dirichlet_group_t G, ulong num)
|
||||
|
||||
Clear discrete logarithm tables in *G*. When discrete logarithm tables are
|
||||
shared with subgroups, those subgroups must be cleared before clearing the
|
||||
tables.
|
||||
|
||||
Conrey elements
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. type:: dirichlet_conrey_struct
|
||||
|
||||
.. type:: dirichlet_conrey_t
|
||||
|
||||
Represents elements of the unit group mod *q*, keeping both the
|
||||
*number* (residue class) and *log* (exponents on the group
|
||||
generators).
|
||||
|
||||
.. function:: void dirichlet_conrey_log(dirichlet_conrey_t x, const dirichlet_group_t G, ulong m)
|
||||
|
||||
Sets *x* to the element of number *m*, computing its log using discrete
|
||||
logarithm in *G*.
|
||||
|
||||
.. function:: ulong dirichlet_conrey_exp(dirichlet_conrey_t x, const dirichlet_group_t G)
|
||||
|
||||
Compute the reverse operation.
|
||||
|
||||
.. function:: void dirichlet_conrey_one(dirichlet_conrey_t x, const dirichlet_group_t G)
|
||||
|
||||
Sets *x* to the *number* `1\in G`, having *log* `[0,\dots 0]`.
|
||||
|
||||
.. function:: void dirichlet_conrey_first_primitive(dirichlet_conrey_t x, const dirichlet_group_t G)
|
||||
|
||||
Sets *x* to the first primitive element of *G*, having *log* `[1,\dots 1]`,
|
||||
or `[0, 1, \dots 1]` if `8\mid q`.
|
||||
|
||||
.. function:: void dirichlet_conrey_set(dirichlet_conrey_t x, const dirichlet_group_t G, const dirichlet_conrey_t y)
|
||||
|
||||
Sets *x* to the element *y*.
|
||||
|
||||
.. function:: int dirichlet_conrey_next(dirichlet_conrey_t x, const dirichlet_group_t G)
|
||||
|
||||
Sets *x* to the next conrey element in *G* with lexicographic ordering.
|
||||
|
||||
The return value
|
||||
is the index of the last updated exponent of *x*, or *-1* if the last
|
||||
element has been reached.
|
||||
|
||||
This function allows to iterate on the elements of *G* looping on their *log*.
|
||||
Note that it produces elements in seemingly random *number* order.
|
||||
|
||||
The following template can be used to loop over all elements *x* in *G*::
|
||||
|
||||
acb_conrey_one(x, G);
|
||||
do {
|
||||
/* use Conrey element x */
|
||||
} while (dirichlet_conrey_next(x, G) >= 0);
|
||||
|
||||
.. function:: int dirichlet_conrey_next_primitive(dirichlet_conrey_t x, const dirichlet_group_t G)
|
||||
|
||||
Same as :func:`dirichlet_conrey_next`, but jumps to the next element
|
||||
corresponding to a primitive character of *G*.
|
||||
|
||||
.. function:: ulong dirichlet_index_conrey(const dirichlet_group_t G, const dirichlet_conrey_t x);
|
||||
|
||||
Returns the lexicographic index of *x* as an integer in `0\dots \varphi(q)`.
|
||||
|
||||
.. function:: void dirichlet_conrey_index(dirichlet_conrey_t x, const dirichlet_group_t G, ulong j)
|
||||
|
||||
Sets *x* to the Conrey element of lexicographic index *j*.
|
||||
|
||||
.. function:: int dirichlet_conrey_eq(const dirichlet_conrey_t x, const dirichlet_conrey_t y)
|
||||
|
||||
.. function:: int dirichlet_conrey_eq_deep(const dirichlet_group_t G, const dirichlet_conrey_t x, const dirichlet_conrey_t y)
|
||||
|
||||
Return 1 if *x* equals *y*.
|
||||
The second version checks every byte of the representation and is intended for testing only.
|
||||
|
||||
Dirichlet characters
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Dirichlet characters take value in a finite cyclic group of roots of unity plus zero.
|
||||
|
||||
When evaluation functions return a *ulong*, this number corresponds to the
|
||||
power of a primitive root of unity, the special value *DIRICHLET_CHI_NULL*
|
||||
encoding the zero value.
|
||||
|
||||
The Conrey numbering scheme makes explicit the mathematical fact that
|
||||
the group *G* is isomorphic to its dual, so that a character is described by
|
||||
a *number*.
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{array}{ccccc}
|
||||
(\mathbb Z/q\mathbb Z)^\times \times (\mathbb Z/q\mathbb Z)^\times & \to & \bigoplus_i \mathbb Z/\phi_i\mathbb Z \times \mathbb Z/\phi_i\mathbb Z & \to &\mathbb C \\
|
||||
(m,n) & \mapsto& (a_i,b_i) &\mapsto& \chi_q(m,n) = \exp(2i\pi\sum \frac{a_ib_i}{\phi_i} )
|
||||
\end{array}
|
||||
|
||||
.. function:: ulong dirichlet_ui_pairing(const dirichlet_group_t G, ulong m, ulong n)
|
||||
|
||||
.. function:: ulong dirichlet_ui_pairing_conrey(const dirichlet_group_t G, const dirichlet_conrey_t a, const dirichlet_conrey_t b)
|
||||
|
||||
Compute the value of the Dirichlet pairing on numbers *m* and *n*, as
|
||||
exponent modulo *G->expo*.
|
||||
The second form takes the Conrey index *a* and *b*, and does not take discrete
|
||||
logarithms.
|
||||
|
||||
The returned value is the numerator of the actual value exponent mod the group exponent *G->expo*.
|
||||
|
||||
Character type
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. type:: dirichlet_char_struct
|
||||
|
||||
.. type:: dirichlet_char_t
|
||||
|
||||
Represents a Dirichlet character. This structure contains various
|
||||
useful invariants such as the order, the parity and the conductor of the character.
|
||||
|
||||
An *dirichlet_char_t* is defined as an array of *dirichlet_char_struct*
|
||||
of length 1, permitting it to be passed by reference.
|
||||
|
||||
.. function:: void dirichlet_char_init(dirichlet_char_t chi, const dirichlet_group_t G)
|
||||
|
||||
Initializes *chi* to an element of the group *G* and sets its value
|
||||
to the principal character.
|
||||
|
||||
.. function:: void dirichlet_char_clear(dirichlet_char_t chi)
|
||||
|
||||
Clears *chi*.
|
||||
|
||||
.. function:: void dirichlet_char(dirichlet_char_t chi, const dirichlet_group_t G, ulong n)
|
||||
|
||||
Sets *chi* to the Dirichlet character of number *n*, using Conrey numbering scheme.
|
||||
This function performs a discrete logarithm in *G*.
|
||||
|
||||
.. function:: void dirichlet_char_conrey(dirichlet_char_t chi, const dirichlet_group_t G, const dirichlet_conrey_t x)
|
||||
|
||||
Sets *chi* to the Dirichlet character corresponding to *x*.
|
||||
|
||||
.. function:: int dirichlet_char_eq(const dirichlet_char_t chi1, const dirichlet_char_t chi2)
|
||||
|
||||
.. function:: int dirichlet_char_eq_deep(const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2)
|
||||
|
||||
Return 1 if *chi1* equals *chi2*.
|
||||
The second version checks every byte of the representation and is intended for testing only.
|
||||
|
||||
.. function:: int dirichlet_char_is_principal(const dirichlet_char_t chi)
|
||||
|
||||
Return 1 if *chi* is the principal character mod *q*.
|
||||
|
||||
.. function:: void dirichlet_char_one(dirichlet_char_t chi, const dirichlet_group_t G)
|
||||
|
||||
Sets *chi* to the principal character.
|
||||
|
||||
.. function:: void dirichlet_char_set(dirichlet_char_t chi1, const dirichlet_group_t G, const dirichlet_char_t chi2)
|
||||
|
||||
Sets *chi1* to the character *chi2*.
|
||||
|
||||
.. function:: int dirichlet_char_next(dirichlet_char_t chi, const dirichlet_group_t G)
|
||||
|
||||
Sets *x* to the next character in *G* with lexicographic Conrey ordering
|
||||
(see :func:`dirichlet_conrey_next`). The return value
|
||||
is the index of the last updated exponent of *x*, or *-1* if the last
|
||||
element has been reached.
|
||||
|
||||
.. function:: int dirichlet_char_next_primitive(dirichlet_char_t chi, const dirichlet_group_t G)
|
||||
|
||||
Like :func:`dirichlet_char_next`, but only generates primitive
|
||||
characters.
|
||||
|
||||
Character properties
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
As a consequence of the Conrey numbering, all these numbers are available at the
|
||||
level of *number* and Conrey *log* elements, and for *char*.
|
||||
No discrete log computation is performed.
|
||||
|
||||
.. function:: ulong dirichlet_number_primitive(const dirichlet_group_t G)
|
||||
|
||||
Return the number of primitive elements in *G*.
|
||||
|
||||
.. function:: ulong dirichlet_ui_conductor(const dirichlet_group_t G, ulong a)
|
||||
|
||||
.. function:: ulong dirichlet_conrey_conductor(const dirichlet_group_t G, const dirichlet_conrey_t x)
|
||||
|
||||
.. function:: ulong dirichlet_char_conductor(const dirichlet_char_t chi)
|
||||
|
||||
Return the *conductor* of `\chi_q(a,\cdot)`, that is the smallest `r` dividing `q`
|
||||
such `\chi_q(a,\cdot)` can be obtained as a character mod `r`.
|
||||
This number is precomputed for the *char* type.
|
||||
|
||||
.. function:: int dirichlet_ui_parity(const dirichlet_group_t G, ulong a)
|
||||
|
||||
.. function:: int dirichlet_conrey_parity(const dirichlet_group_t G, const dirichlet_conrey_t x)
|
||||
|
||||
.. function:: int dirichlet_char_parity(const dirichlet_char_t chi)
|
||||
|
||||
Return the *parity* `\lambda` in `\{0,1\}` of `\chi_q(a,\cdot)`, such that
|
||||
`\chi_q(a,-1)=(-1)^\lambda`.
|
||||
This number is precomputed for the *char* type.
|
||||
|
||||
.. function:: ulong dirichlet_ui_order(const dirichlet_group_t G, ulong a)
|
||||
|
||||
.. function:: ulong dirichlet_conrey_order(const dirichlet_group_t G, const dirichlet_conrey_t x)
|
||||
|
||||
.. function:: ulong dirichlet_char_order(const dirichlet_char_t chi)
|
||||
|
||||
Return the order of `\chi_q(a,\cdot)` which is the order of `a\bmod q`.
|
||||
This number is precomputed for the *char* type.
|
||||
|
||||
.. function:: int dirichlet_char_is_real(const dirichlet_char_t chi)
|
||||
|
||||
Return 1 if *chi* is a real character (iff it has order `\leq 2`).
|
||||
|
||||
Character evaluation
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
The image of a Dirichlet character is a finite cyclic group. Dirichlet
|
||||
character evaluations are exponents in this group.
|
||||
|
||||
.. function:: ulong dirichlet_ui_chi_conrey(const dirichlet_group_t G, const dirichlet_char_t chi, const dirichlet_conrey_t x)
|
||||
|
||||
.. function:: ulong dirichlet_ui_chi(const dirichlet_group_t G, const dirichlet_char_t chi, ulong n)
|
||||
|
||||
Compute that value `\chi(n)` as the exponent mod the order of `\chi`.
|
||||
|
||||
Vector evaluation
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. function:: void dirichlet_ui_chi_vec(ulong * v, const dirichlet_group_t G, const dirichlet_char_t chi, slong nv)
|
||||
|
||||
Compute the list of exponent values *v[k]* for `0\leq k < nv`.
|
||||
|
||||
Character operations
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
.. function:: void dirichlet_conrey_mul(dirichlet_conrey_t c, const dirichlet_group_t G, const dirichlet_conrey_t a, const dirichlet_conrey_t b)
|
||||
|
||||
.. function:: void dirichlet_char_mul(dirichlet_char_t chi12, const dirichlet_group_t G, const dirichlet_char_t chi1, const dirichlet_char_t chi2)
|
||||
|
||||
Multiply two characters in the same group.
|
||||
|
||||
.. function:: void dirichlet_conrey_pow(dirichlet_conrey_t c, const dirichlet_group_t G, const dirichlet_conrey_t a, ulong n)
|
||||
|
||||
Take the power of some character.
|
||||
|
||||
Implementation notes
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
The current implementation introduces a *char* type which contains a *conrey*
|
||||
log plus additional information which
|
||||
|
||||
- makes evaluation of a single character a bit faster
|
||||
|
||||
- has some initialization cost.
|
||||
|
||||
Even if it is straightforward to convert a *conrey* log to the
|
||||
corresponding *char*, looping is faster at the
|
||||
level of Conrey representation. Things can be improved on this aspect
|
||||
but it makes code more intricate.
|
|
@ -118,10 +118,12 @@ modules.
|
|||
acb_hypgeom.rst
|
||||
arb_hypgeom.rst
|
||||
acb_modular.rst
|
||||
dirichlet.rst
|
||||
acb_dirichlet.rst
|
||||
bernoulli.rst
|
||||
hypgeom.rst
|
||||
partitions.rst
|
||||
acb_dft.rst
|
||||
|
||||
Calculus
|
||||
::::::::::::::::::::::::::::::::::::
|
||||
|
|
|
@ -47,15 +47,15 @@ int main(int argc, char *argv[])
|
|||
for (q = qmin; q <= qmax; q++)
|
||||
{
|
||||
ulong k;
|
||||
acb_dirichlet_group_t G;
|
||||
acb_dirichlet_conrey_t x;
|
||||
dirichlet_group_t G;
|
||||
dirichlet_conrey_t x;
|
||||
acb_ptr z;
|
||||
|
||||
if (q % 4 == 2)
|
||||
continue;
|
||||
|
||||
acb_dirichlet_group_init(G, q);
|
||||
acb_dirichlet_conrey_init(x, G);
|
||||
dirichlet_group_init(G, q);
|
||||
dirichlet_conrey_init(x, G);
|
||||
|
||||
z = _acb_vec_init(G->phi_q);
|
||||
|
||||
|
@ -64,11 +64,11 @@ int main(int argc, char *argv[])
|
|||
if (out)
|
||||
{
|
||||
k = 0;
|
||||
acb_dirichlet_conrey_one(x, G);
|
||||
while (acb_dirichlet_conrey_next(x, G) >= 0)
|
||||
dirichlet_conrey_one(x, G);
|
||||
while (dirichlet_conrey_next(x, G) >= 0)
|
||||
{
|
||||
k++;
|
||||
if (acb_dirichlet_conrey_conductor(G,x) < q)
|
||||
if (dirichlet_conrey_conductor(G,x) < q)
|
||||
continue;
|
||||
flint_printf("%wu,%wu: ", q, x->n);
|
||||
acb_printd(z + k, digits);
|
||||
|
@ -77,8 +77,8 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
_acb_vec_clear(z, G->phi_q);
|
||||
acb_dirichlet_conrey_clear(x);
|
||||
acb_dirichlet_group_clear(G);
|
||||
dirichlet_conrey_clear(x);
|
||||
dirichlet_group_clear(G);
|
||||
}
|
||||
acb_clear(s);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue