refactor order

This commit is contained in:
Pascal 2016-06-15 17:25:14 +02:00
parent d676ef27c9
commit 73b253b44c
9 changed files with 150 additions and 47 deletions

View file

@ -27,6 +27,11 @@
extern "C" {
#endif
void _acb_dirichlet_euler_product_real_ui(arb_t res, ulong s,
const signed char * chi, int mod, int reciprocal, slong prec);
void acb_dirichlet_eta(acb_t res, const acb_t s, slong prec);
typedef struct
{
ulong q; /* modulus */
@ -62,11 +67,9 @@ void acb_dirichlet_group_dlog_precompute(acb_dirichlet_group_t G, ulong num);
/* properties of elements without log */
ulong acb_dirichlet_number_primitive(const acb_dirichlet_group_t G);
ulong acb_dirichlet_conductor_ui(const acb_dirichlet_group_t G, ulong a);
int acb_dirichlet_parity_ui(const acb_dirichlet_group_t G, ulong a);
/*
ulong acb_dirichlet_order_ui(const acb_dirichlet_groupt_t G, ulong a);
*/
ulong acb_dirichlet_ui_conductor(const acb_dirichlet_group_t G, ulong a);
int acb_dirichlet_ui_parity(const acb_dirichlet_group_t G, ulong a);
ulong acb_dirichlet_ui_order(const acb_dirichlet_group_t G, ulong a);
/* elements of the group, keep both number and log */
typedef struct
@ -78,11 +81,6 @@ acb_dirichlet_conrey_struct;
typedef acb_dirichlet_conrey_struct acb_dirichlet_conrey_t[1];
void _acb_dirichlet_euler_product_real_ui(arb_t res, ulong s,
const signed char * chi, int mod, int reciprocal, slong prec);
void acb_dirichlet_eta(acb_t res, const acb_t s, slong prec);
void acb_dirichlet_conrey_init(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G);
void acb_dirichlet_conrey_clear(acb_dirichlet_conrey_t x);
void acb_dirichlet_conrey_print(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x);

View file

@ -42,8 +42,8 @@ acb_dirichlet_char_next(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G)
chi->expo[k] = 0;
}
/* should do it with log, but not kept yet */
chi->conductor = acb_dirichlet_conductor_ui(G, chi->n);
/* should do it with log, but log is not kept yet in the struct */
chi->conductor = acb_dirichlet_ui_conductor(G, chi->n);
acb_dirichlet_char_normalize(chi, G);
/* return last index modified */

View file

@ -0,0 +1,38 @@
/*=============================================================================
This file is part of ARB.
ARB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ARB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ARB; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2016 Pascal Molin
******************************************************************************/
#include "acb_dirichlet.h"
ulong
acb_dirichlet_conrey_order(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x)
{
ulong k, g;
g = G->expo;
for (k = 0; k < G->num; k++)
g = n_gcd(g, G->PHI[k] * x->log[k]);
return G->expo / g;
}

View file

@ -26,25 +26,6 @@
#include "acb_dirichlet.h"
/* order of an element knowing the factorization of a multiple */
static ulong
nmod_order_precomp(ulong a, nmod_t mod, ulong expo, n_factor_t fac)
{
int k;
ulong pe, ap, order = 1;
for (k = 0; k < fac.num; k++)
{
pe = n_pow(fac.p[k], fac.exp[k]);
ap = nmod_pow_ui(a, expo / pe, mod);
while ( ap != 1)
{
ap = nmod_pow_ui(ap, fac.p[k], mod);
order *= fac.p[k];
}
}
return order;
}
int main()
{
slong iter, bits;
@ -61,7 +42,6 @@ int main()
acb_dirichlet_group_t G;
acb_dirichlet_char_t chi, chi2;
ulong q, iter2;
n_factor_t fac;
q = 2 + n_randint(state, 1 << bits);
@ -69,9 +49,6 @@ int main()
acb_dirichlet_char_init(chi, G);
acb_dirichlet_char_init(chi2, G);
n_factor_init(&fac);
n_factor(&fac, G->expo, 1);
acb_dirichlet_group_dlog_precompute(G, 50);
/* check number char properties */
@ -87,7 +64,7 @@ int main()
acb_dirichlet_char(chi, G, m);
order = nmod_order_precomp(m, G->mod, G->expo, fac);
order = acb_dirichlet_ui_order(G, m);
if (order != chi->order)
{
flint_printf("FAIL: order\n\n");
@ -98,7 +75,7 @@ int main()
abort();
}
cond = acb_dirichlet_conductor_ui(G, m);
cond = acb_dirichlet_ui_conductor(G, m);
if (cond != acb_dirichlet_char_conductor(G, chi))
{
flint_printf("FAIL: conductor\n\n");
@ -109,7 +86,7 @@ int main()
abort();
}
par = acb_dirichlet_parity_ui(G, m);
par = acb_dirichlet_ui_parity(G, m);
chim1 = acb_dirichlet_ui_chi(G, chi, q - 1);
if (acb_dirichlet_char_parity(chi) != par || par != (chim1 != 0))
{

View file

@ -33,7 +33,7 @@ acb_dirichlet_theta_length_d(ulong q, double x, slong prec)
{
double a, la;
a = PI / (double)q * x * x;
la = (a>.3) ? -log(2*a*(1-a)) : .8;
la = (a < .3) ? -log(2*a*(1-a)) : .8;
la = ((double)prec * LOG2 + la) / a;
return ceil(sqrt(la)+.5);
}

View file

@ -26,7 +26,7 @@
#include "acb_dirichlet.h"
ulong
acb_dirichlet_conductor_ui(const acb_dirichlet_group_t G, ulong a)
acb_dirichlet_ui_conductor(const acb_dirichlet_group_t G, ulong a)
{
slong k;
ulong ap, cond;

55
acb_dirichlet/ui_order.c Normal file
View file

@ -0,0 +1,55 @@
/*=============================================================================
This file is part of ARB.
ARB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ARB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ARB; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2016 Pascal Molin
******************************************************************************/
#include "acb_dirichlet.h"
/* order of an element knowing the factorization of a multiple */
ulong
nmod_order_precomp(ulong a, nmod_t mod, ulong expo, n_factor_t fac)
{
int k;
ulong pe, ap, order = 1;
for (k = 0; k < fac.num; k++)
{
pe = n_pow(fac.p[k], fac.exp[k]);
ap = nmod_pow_ui(a, expo / pe, mod);
while ( ap != 1)
{
ap = nmod_pow_ui(ap, fac.p[k], mod);
order *= fac.p[k];
}
}
return order;
}
ulong
acb_dirichlet_ui_order(const acb_dirichlet_group_t G, ulong a)
{
n_factor_t fac;
n_factor_init(&fac);
n_factor(&fac, G->expo, 1);
return nmod_order_precomp(a, G->mod, G->expo, fac);
}

View file

@ -26,7 +26,7 @@
#include "acb_dirichlet.h"
int
acb_dirichlet_parity_ui(const acb_dirichlet_group_t G, ulong a)
acb_dirichlet_ui_parity(const acb_dirichlet_group_t G, ulong a)
{
slong k;
int par;

View file

@ -29,9 +29,10 @@ 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 generators introduced
in the LMFDB. We call *number* a residue class, and *index* the
corresponding vector of exponents.
This implementation relies on the Conrey numbering scheme
introduced in the LMFDB.
We call *number* a residue class modulo *q*, and *index* the
corresponding vector of exponents of Conrey generators.
Going from an *index* to the corresponding *number* is a cheap
operation while the converse requires computing discrete
@ -79,6 +80,9 @@ logarithms.
If *num* gets very large, the entire group may be indexed.
Conrey index
...............................................................................
.. type:: acb_dirichlet_conrey_struct
.. type:: acb_dirichlet_conrey_t
@ -130,12 +134,43 @@ the group *G* is isomorphic to its dual.
The returned value is the numerator of the actual value exponent mod the group exponent *G->expo*.
Character properties
...............................................................................
As a consequence of the Conrey numbering, properties of
characters such that the order, the parity or the conductor are available
at the level of their number, whithout any discrete log computation,
or at the Conrey index level.
.. function:: ulong acb_dirichlet_ui_order(const acb_dirichlet_group_t G, ulong a)
.. function:: ulong acb_dirichlet_conrey_order(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x)
Compute the order of a mod q.
.. 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)
Compute the conductor of a mod q, that is the smallest r dividing q such
that a corresponds to an element defined modulo r.
.. function:: ulong 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)
Compute the parity of a mod q, which is the parity of the corresponding
Dirichlet character.
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 of the character.
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.
@ -156,13 +191,13 @@ the group *G* is isomorphic to its dual.
Sets *chi* to the Dirichlet character of Conrey index *x*.
Character properties
-------------------------------------------------------------------------------
...............................................................................
.. function:: ulong acb_dirichlet_char_order(const acb_dirichlet_char_t chi)
.. function:: int acb_dirichlet_char_parity(const acb_dirichlet_char_t chi)
.. function:: ulong acb_dirichlet_char_conductor(const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi)
.. function:: ulong acb_dirichlet_char_conductor(const acb_dirichlet_char_t chi)
Character evaluation
-------------------------------------------------------------------------------