arb/doc/source/acb_dirichlet.rst

639 lines
26 KiB
ReStructuredText
Raw Normal View History

.. _acb-dirichlet:
**acb_dirichlet.h** -- Dirichlet L-functions, zeta functions, and related functions
===================================================================================
2016-09-08 16:53:21 +02:00
*Warning: the interfaces in this module are experimental and may change
without notice.*
2016-09-08 16:53:21 +02:00
This module allows working with Dirichlet characters, Dirichlet L-functions,
and related functions.
A Dirichlet L-function is the analytic continuation of an L-series
.. math ::
L(s,\chi) = \sum_{k=1}^\infty \frac{\chi(k)}{k^s}
where `\chi(k)` is a Dirichlet character.
2016-09-08 16:53:21 +02:00
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.
2016-06-15 17:25:14 +02:00
This implementation relies on the Conrey numbering scheme
2016-09-16 16:08:18 +02:00
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)
2016-09-21 15:04:01 +02:00
We call *number* a residue class `x` modulo *q*, and *log* the
2016-09-16 16:08:18 +02:00
corresponding vector `(e_i)` of exponents of Conrey generators.
2016-09-21 15:04:01 +02:00
Going from a *log* to the corresponding *number* is a cheap
operation called exp, while the converse requires computing discrete
logarithms.
2016-02-23 01:24:31 +01:00
.. type:: acb_dirichlet_group_struct
2016-02-23 01:24:31 +01:00
.. 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
-------------------------------------------------------------------------------
2016-06-15 17:25:14 +02:00
.. type:: acb_dirichlet_conrey_struct
.. type:: acb_dirichlet_conrey_t
Represents elements of the unit group mod *q*, keeping both the
2016-09-21 15:04:01 +02:00
*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)
2016-09-21 15:04:01 +02:00
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)
2016-09-21 15:04:01 +02:00
Sets *x* to the *number* `1\in G`, having *log* `[0,\dots 0]`.
2016-09-18 22:32:53 +02:00
.. function:: void acb_dirichlet_conrey_first_primitive(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G)
2016-09-21 15:04:01 +02:00
Sets *x* to the first primitive element of *G*, having *log* `[1,\dots 1]`,
2016-09-18 22:32:53 +02:00
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)
2016-09-21 15:04:01 +02:00
Sets *x* to the next conrey element in *G* with lexicographic ordering.
2016-09-18 22:32:53 +02:00
2016-09-09 21:53:31 +02:00
The return value
is the index of the last updated exponent of *x*, or *-1* if the last
element has been reached.
2016-09-21 15:04:01 +02:00
This function allows to iterate on the elements of *G* looping on their *log*.
2016-09-09 21:53:31 +02:00
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);
2016-09-18 22:32:53 +02:00
.. 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*.
2016-09-09 21:53:31 +02:00
2016-09-21 15:04:01 +02:00
.. 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*.
2016-09-16 16:08:18 +02:00
.. function:: int acb_dirichlet_conrey_eq(const acb_dirichlet_conrey_t x, const acb_dirichlet_conrey_t y)
2016-09-09 21:53:31 +02:00
2016-09-16 16:08:18 +02:00
.. 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.
2016-09-09 21:53:31 +02:00
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
2016-09-16 16:08:18 +02:00
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)
2016-09-09 21:53:31 +02:00
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.
2016-09-09 21:53:31 +02:00
The returned value is the numerator of the actual value exponent mod the group exponent *G->expo*.
2016-06-15 17:25:14 +02:00
Character type
-------------------------------------------------------------------------------
.. type:: acb_dirichlet_char_struct
.. type:: acb_dirichlet_char_t
Represents a Dirichlet character. This structure contains various
2016-06-15 17:25:14 +02:00
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.
2016-09-08 16:53:21 +02:00
.. function:: void acb_dirichlet_char_init(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G)
2016-09-14 14:27:36 +02:00
Initializes *chi* to an element of the group *G* and sets its value
to the principal character.
2016-09-08 16:53:21 +02:00
.. function:: void acb_dirichlet_char_clear(acb_dirichlet_char_t chi)
2016-09-14 14:27:36 +02:00
Clears *chi*.
2016-09-08 16:53:21 +02:00
.. 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*.
2016-09-08 16:53:21 +02:00
.. function:: void acb_dirichlet_char_conrey(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x)
2016-09-21 15:04:01 +02:00
Sets *chi* to the Dirichlet character corresponding to *x*.
2016-09-16 16:08:18 +02:00
.. 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)
2016-09-09 21:53:31 +02:00
Return 1 if *chi1* equals *chi2*.
2016-09-16 16:08:18 +02:00
The second version checks every byte of the representation and is intended for testing only.
2016-09-09 21:53:31 +02:00
.. function:: acb_dirichlet_char_is_principal(const acb_dirichlet_char_t chi)
2016-09-18 22:32:53 +02:00
Return 1 if *chi* is the principal character mod *q*.
2016-09-09 21:53:31 +02:00
2016-09-14 14:27:36 +02:00
.. function:: void acb_dirichlet_char_one(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G)
Sets *chi* to the principal character.
2016-09-18 22:32:53 +02:00
.. 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*.
2016-09-14 14:27:36 +02:00
.. 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
2016-09-21 15:04:01 +02:00
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)
2016-09-10 12:14:10 +02:00
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)
2016-06-15 17:25:14 +02:00
.. function:: ulong acb_dirichlet_char_conductor(const acb_dirichlet_char_t chi)
2016-09-08 16:53:21 +02:00
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)
2016-09-08 16:53:21 +02:00
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)
2016-09-14 13:47:33 +02:00
Return the order of `\chi_q(a,\cdot)` which is the order of `a\bmod q`.
This number is precomputed for the *char* type.
2016-09-14 14:27:36 +02:00
.. function:: int acb_dirichlet_char_is_real(const acb_dirichlet_char_t chi)
2016-09-09 21:53:31 +02:00
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)
2016-09-16 16:08:18 +02:00
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)
Sets *res* to `\chi(n)`, the value of the Dirichlet character *chi*
at the integer *n*.
There are no restrictions on *n*.
2016-07-21 18:43:52 +02:00
Roots of unity
-------------------------------------------------------------------------------
.. type:: acb_dirichlet_powers_struct
.. type:: acb_dirichlet_powers_t
2016-09-08 16:53:21 +02:00
This structure allows to compute *n* powers of a fixed root of unity of order *m*
2016-07-21 18:43:52 +02:00
using precomputations. Extremal cases are
2016-09-08 16:53:21 +02:00
- all powers are stored: `O(m)` initialization + storage, `O(n)` evaluations
2016-07-21 18:43:52 +02:00
2016-09-08 16:53:21 +02:00
- nothing stored: `O(1)` initialization + storage, `O(\log(m)n)` evaluations
2016-07-21 18:43:52 +02:00
2016-09-08 16:53:21 +02:00
- `k` step decomposition: `O(k m^{\frac1k})` init + storage, `O((k-1)n)` evaluations.
2016-07-21 18:43:52 +02:00
Currently, only baby-step giant-step decomposition (i.e. `k=2`)
is implemented, allowing to obtain each power using one multiplication.
.. function:: void acb_dirichlet_powers_init(acb_dirichlet_powers_t t, ulong order, slong num, slong prec)
2016-09-08 16:53:21 +02:00
Initialize the powers structure for *num* evaluations of powers of the root of unity
2016-07-21 18:43:52 +02:00
of order *order*.
.. function:: void acb_dirichlet_powers_clear(acb_dirichlet_powers_t t)
2016-09-08 16:53:21 +02:00
Clears *t*.
2016-07-21 18:43:52 +02:00
.. function:: void acb_dirichlet_power(acb_t z, const acb_dirichlet_powers_t t, ulong n, slong prec)
2016-09-08 16:53:21 +02:00
Sets *z* to `x^n` where *t* contains precomputed powers of `x`.
2016-07-21 18:43:52 +02:00
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)
2016-09-08 16:53:21 +02:00
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)
2016-09-08 16:53:21 +02:00
Compute the *nv* first Dirichlet values.
2016-09-08 16:53:21 +02:00
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)
2016-09-08 16:53:21 +02:00
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)
2016-09-08 16:53:21 +02:00
Take the power of some character.
2016-08-05 16:13:40 +02:00
Gauss and Jacobi sums
-------------------------------------------------------------------------------
2016-09-16 16:08:18 +02:00
.. 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_factor(acb_t res, const acb_dirichlet_group_t G, const acb_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_theta(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong prec)
2016-08-05 16:13:40 +02:00
.. function:: void acb_dirichlet_gauss_sum(acb_t res, const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi, slong prec)
2016-09-16 16:08:18 +02:00
.. function:: void acb_dirichlet_gauss_sum_ui(acb_t res, const acb_dirichlet_group_t G, ulong a, slong prec)
2016-09-08 16:53:21 +02:00
Compute the Gauss sum
2016-08-05 16:13:40 +02:00
.. math::
2016-09-16 16:08:18 +02:00
G_q(a) = \sum_{x \bmod q} \chi_q(a, x) e^{\frac{2i\pi x}q}
- the *naive* version computes the sum as defined.
- the *factor* version writes it as a product of local Gauss sums by chinese
remainder theorem.
- the *order2* version assumes *chi* is real and primitive and returns
`i^p\sqrt q` where `p` is the parity of `\chi`.
- the *theta* version assumes that *chi* is primitive to obtain the Gauss
sum by functional equation of the theta series at `t=1`. An abort will be
raised if the theta series vanishes at `t=1`. Only 4 exceptional
characters of conductor 300 and 600 are known to have this particularity,
and none with primepower modulus.
- the default version automatically combines the above methods.
- 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)
2016-09-16 17:13:31 +02:00
.. 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)
2016-09-16 16:08:18 +02:00
2016-09-16 17:13:31 +02:00
.. 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)
2016-08-05 16:13:40 +02:00
.. 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)
2016-09-16 17:13:31 +02:00
.. function:: void acb_dirichlet_jacobi_sum_ui(acb_t res, const acb_dirichlet_group_t G, ulong a, ulong b, slong prec)
2016-09-16 16:08:18 +02:00
2016-09-08 16:53:21 +02:00
Compute the Jacobi sum
2016-08-05 16:13:40 +02:00
.. math::
2016-09-14 13:47:33 +02:00
J_q(a,b) = \sum_{x \bmod q} \chi_q(a, x)\chi_q(b, 1-x)
2016-08-05 16:13:40 +02:00
2016-09-16 16:08:18 +02:00
- the *naive* version computes the sum as defined.
- the *factor* version writes it as a product of local Jacobi sums
- the *gauss* version assumes `ab` is primitive and uses the formula
`J_q(a,b)G_q(ab) = G_q(a)G_q(b)`
- the default version automatically combines the above methods.
- the *ui* version only takes the Conrey numbers *a* and *b* as parameters.
2016-07-21 18:43:52 +02:00
Theta sums
-------------------------------------------------------------------------------
2016-09-08 16:53:21 +02:00
We call *theta series* of a Dirichlet character the quadratic series
2016-07-21 18:43:52 +02:00
.. math::
\Theta_q(a) = \sum_{n\geq 0} \chi_q(a, n) n^p x^{n^2}
where `p` is the parity of the character `\chi_q(a,\cdot)`.
For `\Re(t)>0` we write `x(t)=\exp(-\frac{\pi}{N}t^2)` and define
.. math::
\Theta_q(a,t) = \sum_{n\geq 0} \chi_q(a, n) x(t)^{n^2}.
2016-09-14 13:47:33 +02:00
.. 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)
2016-07-21 18:43:52 +02:00
2016-09-14 13:47:33 +02:00
.. function:: void acb_dirichlet_ui_theta_arb(acb_t res, const acb_dirichlet_group_t G, ulong a, const arb_t t, slong prec)
2016-07-21 18:43:52 +02:00
2016-09-08 16:53:21 +02:00
Compute the theta series `\Theta_q(a,t)` for real argument `t>0`.
2016-07-21 18:43:52 +02:00
Beware that if `t<1` the functional equation
2016-09-09 21:53:31 +02:00
2016-07-21 18:43:52 +02:00
.. math::
2016-09-09 21:53:31 +02:00
2016-09-14 13:47:33 +02:00
t \theta(a,t) = \epsilon(\chi) \theta\left(\frac1a, \frac1t\right)
2016-09-09 21:53:31 +02:00
2016-07-21 18:43:52 +02:00
should be used, which is not done automatically (to avoid recomputing the
Gauss sum).
.. function:: ulong acb_dirichlet_theta_length(ulong q, const arb_t t, slong prec)
2016-09-08 16:53:21 +02:00
Compute the number of terms to be summed in the theta series of argument *t*
2016-07-21 18:43:52 +02:00
so that the tail is less than `2^{-\mathrm{prec}}`.
2016-09-09 21:53:31 +02:00
.. function:: void acb_dirichlet_qseries_powers_naive(acb_t res, const arb_t x, int p, const ulong * a, const acb_dirichlet_powers_t z, slong len, slong prec)
2016-07-21 18:43:52 +02:00
2016-09-09 21:53:31 +02:00
.. function:: void acb_dirichlet_qseries_powers_smallorder(acb_t res, const arb_t x, int p, const ulong * a, const acb_dirichlet_powers_t z, slong len, slong prec)
2016-07-21 18:43:52 +02:00
2016-09-08 16:53:21 +02:00
Compute the series `\sum n^p z^{a_n} x^{n^2}` for exponent list *a*,
2016-07-21 18:43:52 +02:00
precomputed powers *z* and parity *p* (being 0 or 1).
2016-09-09 21:53:31 +02:00
2016-07-21 18:43:52 +02:00
The *naive* version sums the series as defined, while the *smallorder*
variant evaluates the series on the quotient ring by a cyclotomic polynomial
before evaluating at the root of unity, ignoring its argument *z*.
2016-08-05 16:13:40 +02:00
Discrete Fourier Transforms (DFT)
2016-06-17 18:23:48 +02:00
-------------------------------------------------------------------------------
2016-08-05 16:13:40 +02:00
Let *G* be a finite abelian group, and `\chi` a character of *G*.
2016-08-06 14:09:00 +02:00
For any map `f:G\to\mathbb C`, the discrete fourier transform
`\hat f:\hat G\to \mathbb C` is defined by
2016-06-17 18:23:48 +02:00
2016-08-05 16:13:40 +02:00
.. math::
2016-08-05 16:13:40 +02:00
\hat f(\chi) = \sum_{x\in G}\chi(x)f(x)
2016-08-05 16:13:40 +02:00
Fast Fourier Transform techniques allow to compute efficiently
all values `\hat f(\chi)`.
2016-08-05 16:13:40 +02:00
For a Dirichlet group `G` modulo `q`, we take advantage
of the Conrey isomorphism `G \to \hat G` to consider the
the Fourier transform on Conrey labels as
2016-06-17 18:23:48 +02:00
2016-08-05 16:13:40 +02:00
.. math::
2016-08-05 16:13:40 +02:00
g(a) = \sum_{b\bmod q}\chi_q(a,b)f(b)
2016-08-05 16:13:40 +02:00
.. function:: void acb_dirichlet_dft_conrey(acb_ptr w, acb_srcptr v, const acb_dirichlet_group_t G, slong prec)
2016-09-08 16:53:21 +02:00
Compute the DFT of *v* using Conrey indices.
2016-08-05 16:13:40 +02:00
This function assumes *v* and *w* are vectors
of size *G->phi_q*, whose values correspond to a lexicographic ordering
2016-09-21 15:04:01 +02:00
of Conrey logs (as obtained using :func:`acb_dirichlet_conrey_next` or
by :func:`acb_dirichlet_index_conrey`).
2016-08-05 16:13:40 +02:00
For example, if `q=15`, the Conrey elements are stored in following
order
2016-09-21 15:04:01 +02:00
======= ============= =====================
index log = [e,f] number = 7^e 11^f
======= ============= =====================
0 [0, 0] 1
1 [0, 1] 7
2 [0, 2] 4
3 [0, 3] 13
4 [0, 4] 1
5 [1, 0] 11
6 [1, 1] 2
7 [1, 2] 14
8 [1, 3] 8
9 [1, 4] 11
======= ============= =====================
2016-08-05 16:13:40 +02:00
.. function:: void acb_dirichlet_dft(acb_ptr w, acb_srcptr v, const acb_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*.
All values at index not coprime to *G->q* are ignored.
Euler products
-------------------------------------------------------------------------------
.. function:: void _acb_dirichlet_euler_product_real_ui(arb_t res, ulong s, const signed char * chi, int mod, int reciprocal, slong prec)
Sets *res* to `L(s,\chi)` where `\chi` is a real Dirichlet character
given by the explicit list *chi* of character values at
0, 1, ..., *mod* - 1. If *reciprocal* is set, computes `1 / L(s,\chi)`
(this is faster if the reciprocal can be used directly).
This function uses the Euler product, and is only intended for use when
*s* is large. An error bound is computed via :func:`mag_hurwitz_zeta_uiui`.
Since
.. math ::
\frac{1}{L(s,\chi)} = \prod_{p} \left(1 - \frac{\chi(p)}{p^s}\right)
= \sum_{k=1}^{\infty} \frac{\mu(k)\chi(k)}{k^s}
and the truncated product gives all smooth-index terms in the series, we have
.. math ::
\left|\prod_{p < N} \left(1 - \frac{\chi(p)}{p^s}\right) - \frac{1}{L(s,\chi)}\right|
\le \sum_{k=N}^{\infty} \frac{1}{k^s} = \zeta(s,N).
Simple functions
-------------------------------------------------------------------------------
.. function:: void acb_dirichlet_eta(acb_t res, const acb_t s, slong prec)
Sets *res* to the Dirichlet eta function
`\eta(s) = \sum_{k=1}^{\infty} (-1)^k / k^s = (1-2^{1-s}) \zeta(s)`,
also known as the alternating zeta function.
Note that the alternating character `\{1,-1\}` is not itself
a Dirichlet character.
2016-09-08 16:53:21 +02:00
L-functions
2016-08-06 14:09:00 +02:00
-------------------------------------------------------------------------------
2016-09-22 16:43:41 +02:00
.. 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(acb_t res, const acb_dirichlet_group_t G, const acb_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)
The *theta* variant uses the evaluation at `t=1` of the Theta series.
The default version computes it via the gauss sum.
2016-08-06 14:09:00 +02:00
.. 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)
2016-09-10 12:14:10 +02:00
Compute `L(s,\chi)` using decomposition in terms of the Hurwitz zeta function
2016-08-06 14:09:00 +02:00
2016-09-10 12:14:10 +02:00
.. math::
L(s,\chi) = q^{-s}\sum_{k=1}^{q-1} \chi(k) \,\zeta\!\left(s,\frac kq\right).
2016-08-06 14:09:00 +02:00
2016-09-10 12:14:10 +02:00
If `s = 1` and `\chi` is non-principal, the deflated Hurwitz zeta function
is used to avoid poles.
2016-08-06 14:09:00 +02:00
2016-09-10 12:14:10 +02:00
This formula is slow for large *q*.
2016-08-06 14:09:00 +02:00
.. function:: void acb_dirichlet_l_vec_hurwitz(acb_ptr res, const acb_t s, const acb_dirichlet_group_t G, slong prec)
2016-09-10 12:14:10 +02:00
Compute all values `L(s,\chi)` for `\chi` mod `q`, by Hurwitz formula and
discrete Fourier transform.
2016-09-21 15:04:01 +02:00
*res* is assumed to have length *G->phi_q* and values are stored by lexicographically ordered
Conrey logs. See :func:`acb_dirichlet_dft_conrey`.
2016-06-17 18:23:48 +02:00
Implementation notes
-------------------------------------------------------------------------------
The current implementation introduces a *char* type which contains a *conrey*
2016-09-21 15:04:01 +02:00
log plus additional information which
2016-06-17 18:23:48 +02:00
2016-09-08 16:53:21 +02:00
- makes evaluation of a single character a bit faster
2016-06-17 18:23:48 +02:00
2016-09-08 16:53:21 +02:00
- has some initialization cost.
2016-06-17 18:23:48 +02:00
2016-09-21 15:04:01 +02:00
Even if it is straightforward to convert a *conrey* log to the
2016-06-17 18:23:48 +02:00
corresponding *char*, looping is faster at the
2016-09-08 16:53:21 +02:00
level of Conrey representation. Things can be improved on this aspect
2016-06-17 18:23:48 +02:00
but it makes code more intricate.