From f44c6843fd689cb469287e454bac3d9075c96e33 Mon Sep 17 00:00:00 2001 From: Fredrik Johansson Date: Thu, 1 Dec 2016 22:33:15 +0100 Subject: [PATCH] use acb_dirichlet_roots_t in l_hurwitz and l_jet; rename dirichlet_number_primitive -> dirichlet_group_num_primitive --- acb_dirichlet/l_hurwitz.c | 15 ++++++++------- acb_dirichlet/l_jet.c | 15 +++++++++------ acb_dirichlet/test/t-l_hurwitz.c | 2 +- dirichlet.h | 3 ++- .../{number_primitive.c => group_num_primitive.c} | 2 +- dirichlet/test/t-chars.c | 2 +- doc/source/dirichlet.rst | 12 ++++++++---- 7 files changed, 30 insertions(+), 21 deletions(-) rename dirichlet/{number_primitive.c => group_num_primitive.c} (93%) diff --git a/acb_dirichlet/l_hurwitz.c b/acb_dirichlet/l_hurwitz.c index 1120a8ba..39a41ce8 100644 --- a/acb_dirichlet/l_hurwitz.c +++ b/acb_dirichlet/l_hurwitz.c @@ -19,9 +19,9 @@ acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, const dirichlet_group_t G, const dirichlet_char_t chi, slong prec) { ulong order, chin, mult; - acb_t t, u, a; - acb_ptr z; + acb_t t, u, a, w; dirichlet_char_t cn; + acb_dirichlet_roots_t roots; int deflate; /* remove pole in Hurwitz zeta at s = 1 */ @@ -40,6 +40,7 @@ acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, acb_init(t); acb_init(u); acb_init(a); + acb_init(w); dirichlet_char_one(cn, G); acb_zero(t); @@ -48,9 +49,7 @@ acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, order = dirichlet_order_char(G, chi); mult = G->expo / order; - z = _acb_vec_init(order); - /* todo: use roots object */ - _acb_vec_unit_roots(z, order, prec); + acb_dirichlet_roots_init(roots, order, dirichlet_group_size(G), prec); do { chin = dirichlet_pairing_char(G, chi, cn) / mult; @@ -70,7 +69,8 @@ acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, acb_dirichlet_hurwitz_precomp_eval(u, precomp, cn->n, G->q, prec); } - acb_addmul(t, z + chin, u, prec); + acb_dirichlet_root(w, roots, chin, prec); + acb_addmul(t, u, w, prec); } while (dirichlet_char_next(cn, G) >= 0); @@ -81,9 +81,10 @@ acb_dirichlet_l_hurwitz(acb_t res, const acb_t s, dirichlet_char_clear(cn); - _acb_vec_clear(z, order); + acb_dirichlet_roots_clear(roots); acb_clear(t); acb_clear(u); acb_clear(a); + acb_clear(w); } diff --git a/acb_dirichlet/l_jet.c b/acb_dirichlet/l_jet.c index 819f5870..119092cc 100644 --- a/acb_dirichlet/l_jet.c +++ b/acb_dirichlet/l_jet.c @@ -19,9 +19,10 @@ acb_dirichlet_l_jet(acb_ptr res, const acb_t s, int deflate, slong len, slong prec) { ulong order, chin, mult, phi; - acb_t a; - acb_ptr t, u, z; + acb_t a, w; + acb_ptr t, u; dirichlet_char_t cn; + acb_dirichlet_roots_t roots; int deflate_hurwitz; if (len <= 0) @@ -52,6 +53,7 @@ acb_dirichlet_l_jet(acb_ptr res, const acb_t s, t = _acb_vec_init(len); u = _acb_vec_init(len + 2); acb_init(a); + acb_init(w); dirichlet_char_one(cn, G); @@ -59,8 +61,7 @@ acb_dirichlet_l_jet(acb_ptr res, const acb_t s, order = dirichlet_order_char(G, chi); mult = G->expo / order; - z = _acb_vec_init(order); - _acb_vec_unit_roots(z, order, prec); + acb_dirichlet_roots_init(roots, order, dirichlet_group_size(G), prec); phi = 0; do @@ -69,7 +70,8 @@ acb_dirichlet_l_jet(acb_ptr res, const acb_t s, acb_set_ui(a, cn->n); acb_div_ui(a, a, G->q, prec); _acb_poly_zeta_cpx_series(u, s, a, deflate_hurwitz, len, prec); - _acb_vec_scalar_addmul(t, u, len, z + chin, prec); + acb_dirichlet_root(w, roots, chin, prec); + _acb_vec_scalar_addmul(t, u, len, w, prec); phi++; } while (dirichlet_char_next(cn, G) >= 0); @@ -112,9 +114,10 @@ acb_dirichlet_l_jet(acb_ptr res, const acb_t s, dirichlet_char_clear(cn); - _acb_vec_clear(z, order); + acb_dirichlet_roots_clear(roots); _acb_vec_clear(t, len); _acb_vec_clear(u, len + 2); acb_clear(a); + acb_clear(w); } diff --git a/acb_dirichlet/test/t-l_hurwitz.c b/acb_dirichlet/test/t-l_hurwitz.c index fe52f139..db0b630d 100644 --- a/acb_dirichlet/test/t-l_hurwitz.c +++ b/acb_dirichlet/test/t-l_hurwitz.c @@ -71,7 +71,7 @@ int main() "-1.43652482351673593824956935036654893593947145947637807" }; - flint_printf("l...."); + flint_printf("l_hurwitz...."); fflush(stdout); x = _acb_vec_init(nx); diff --git a/dirichlet.h b/dirichlet.h index cdd8713a..4b6e7176 100644 --- a/dirichlet.h +++ b/dirichlet.h @@ -62,6 +62,8 @@ dirichlet_group_size(const dirichlet_group_t G) return G->phi_q; } +ulong dirichlet_group_num_primitive(const dirichlet_group_t G); + void dirichlet_group_init(dirichlet_group_t G, ulong q); void dirichlet_subgroup_init(dirichlet_group_t H, const dirichlet_group_t G, ulong h); void dirichlet_group_clear(dirichlet_group_t G); @@ -70,7 +72,6 @@ void dirichlet_group_dlog_clear(dirichlet_group_t G); /* properties of elements without log */ -ulong dirichlet_number_primitive(const dirichlet_group_t G); ulong dirichlet_conductor_ui(const dirichlet_group_t G, ulong a); int dirichlet_parity_ui(const dirichlet_group_t G, ulong a); ulong dirichlet_order_ui(const dirichlet_group_t G, ulong a); diff --git a/dirichlet/number_primitive.c b/dirichlet/group_num_primitive.c similarity index 93% rename from dirichlet/number_primitive.c rename to dirichlet/group_num_primitive.c index 202e5114..f1c344c2 100644 --- a/dirichlet/number_primitive.c +++ b/dirichlet/group_num_primitive.c @@ -12,7 +12,7 @@ #include "dirichlet.h" ulong -dirichlet_number_primitive(const dirichlet_group_t G) +dirichlet_group_num_primitive(const dirichlet_group_t G) { if (G->q % 4 == 2) return 0; diff --git a/dirichlet/test/t-chars.c b/dirichlet/test/t-chars.c index 5cffdce0..11e0c953 100644 --- a/dirichlet/test/t-chars.c +++ b/dirichlet/test/t-chars.c @@ -74,7 +74,7 @@ int main() dirichlet_char_first_primitive(x, G); for (n = 1; dirichlet_char_next_primitive(x, G) >= 0; n++); - ref = dirichlet_number_primitive(G); + ref = dirichlet_group_num_primitive(G); if (n != ref) { flint_printf("FAIL: number of primitive elements\n\n"); diff --git a/doc/source/dirichlet.rst b/doc/source/dirichlet.rst index 09818810..00520f67 100644 --- a/doc/source/dirichlet.rst +++ b/doc/source/dirichlet.rst @@ -82,6 +82,14 @@ Multiplicative group modulo *q* Clears *G*. Remark this function does *not* clear the discrete logarithm tables stored in *G* (which may be shared with another group). +.. function:: ulong dirichlet_group_size(const dirichlet_group_t G) + + Returns the number of elements in *G*, i.e. `\varphi(q)`. + +.. function:: ulong dirichlet_group_num_primitive(const dirichlet_group_t G) + + Returns the number of primitive elements in *G*. + .. function:: void dirichlet_group_dlog_precompute(dirichlet_group_t G, ulong num) Precompute decomposition and tables for discrete log computations in *G*, @@ -194,10 +202,6 @@ Character properties As a consequence of the Conrey numbering, all these numbers are available at the level of *number* and *char* object. Both case require no discrete log computation. -.. function:: ulong dirichlet_number_primitive(const dirichlet_group_t G) - - Returns the number of primitive elements in *G*. - .. function:: int dirichlet_char_is_principal(const dirichlet_group_t G, const dirichlet_char_t chi) Returns 1 if *chi* is the principal character mod *q*.