add conductor inside char type

This commit is contained in:
Pascal 2016-06-15 11:33:01 +02:00
parent ce4b6c16e2
commit cc12103e8e
8 changed files with 172 additions and 32 deletions

View file

@ -49,6 +49,16 @@ acb_dirichlet_group_struct;
typedef acb_dirichlet_group_struct acb_dirichlet_group_t[1];
ACB_DIRICHLET_INLINE ulong
acb_dirichlet_group_size(const acb_dirichlet_group_t G)
{
return G->phi_q;
}
void acb_dirichlet_group_init(acb_dirichlet_group_t G, ulong q);
void acb_dirichlet_group_clear(acb_dirichlet_group_t G);
void acb_dirichlet_group_dlog_precompute(acb_dirichlet_group_t G, ulong num);
/* elements of the group, keep both number and log */
typedef struct
{
@ -64,16 +74,12 @@ void _acb_dirichlet_euler_product_real_ui(arb_t res, ulong s,
void acb_dirichlet_eta(acb_t res, const acb_t s, slong prec);
void acb_dirichlet_group_init(acb_dirichlet_group_t G, ulong q);
void acb_dirichlet_group_clear(acb_dirichlet_group_t G);
void acb_dirichlet_group_dlog_precompute(acb_dirichlet_group_t G, ulong num);
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);
int acb_dirichlet_conrey_parity(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x);
ulong acb_dirichlet_conrey_conductor(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x);
void acb_dirichlet_conrey_log(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G, ulong m);
void acb_dirichlet_conrey_one(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G);
@ -82,6 +88,9 @@ void acb_dirichlet_conrey_first_primitive(acb_dirichlet_conrey_t x, const acb_di
int acb_dirichlet_conrey_next(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G);
int acb_dirichlet_conrey_next_primitive(acb_dirichlet_conrey_t x, const acb_dirichlet_group_t G);
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);
void acb_dirichlet_conrey_pow(acb_dirichlet_conrey_t c, const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t a, ulong n);
#define ACB_DIRICHLET_CHI_NULL UWORD_MAX
ulong acb_dirichlet_ui_pairing_conrey(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t a, const acb_dirichlet_conrey_t b);
@ -92,7 +101,7 @@ void acb_dirichlet_pairing(acb_t res, const acb_dirichlet_group_t G, ulong m, ul
/* introducing character type */
/* character = reduced exponents, keep order and number */
/* character = reduced exponents, keep order, number and conductor */
typedef struct
{
ulong q; /* modulus */
@ -101,6 +110,7 @@ typedef struct
ulong order; /* order */
ulong * expo; /* reduced exponents ( order * log[k] / gcd( ) ) */
int parity; /* 0 for even char, 1 for odd */
ulong conductor;
}
acb_dirichlet_char_struct;

View file

@ -28,29 +28,5 @@
ulong
acb_dirichlet_char_conductor(const acb_dirichlet_group_t G, const acb_dirichlet_char_t chi)
{
int k, f;
ulong cond = 1;
if (G->neven >= 1 && chi->expo[0] == 1)
cond = 4;
if (G->neven == 2 && chi->expo[1])
{
ulong l2 = chi->expo[1];
f = n_remove(&l2, 2);
cond = G->primepowers[1] >> f;
}
for (k = G->neven; k < G->neven; k++)
{
if (chi->expo[k])
{
ulong p, lp;
p = G->primes[k];
lp = chi->expo[k];
f = n_remove(&lp, p);
if (f)
cond *= n_pow(p, G->exponents[k] - f);
else
cond *= G->primepowers[k];
}
}
return cond;
return chi->conductor;
}

View file

@ -34,6 +34,7 @@ acb_dirichlet_char_conrey(acb_dirichlet_char_t chi, const acb_dirichlet_group_t
chi->q = G->q;
chi->n = x->n;
chi->parity = acb_dirichlet_conrey_parity(G, x);
chi->conductor = acb_dirichlet_conrey_conductor(G, x);
for (k = 0; k < G->num; k++)
chi->expo[k] = (x->log[k] * G->PHI[k]) % G->expo;

View file

@ -33,5 +33,6 @@ acb_dirichlet_char_first_primitive(acb_dirichlet_char_t chi, const acb_dirichlet
x->log = chi->expo;
acb_dirichlet_conrey_first_primitive(x, G);
chi->n = x->n;
chi->conductor = chi->q;
acb_dirichlet_char_normalize(chi, G);
}

View file

@ -36,4 +36,5 @@ acb_dirichlet_char_one(acb_dirichlet_char_t chi, const acb_dirichlet_group_t G)
chi->expo[k] = 0;
chi->order = 1;
chi->conductor = 1;
}

View file

@ -0,0 +1,59 @@
/*=============================================================================
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_conductor(const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t x)
{
int k, f;
ulong cond = 1;
if (G->neven >= 1 && x->log[0] == 1)
cond = 4;
if (G->neven == 2 && x->log[1])
{
ulong l2 = x->log[1];
f = n_remove(&l2, 2);
cond = G->primepowers[1] >> f;
}
for (k = G->neven; k < G->num; k++)
{
if (x->log[k])
{
ulong p, lp;
p = G->primes[k];
lp = x->log[k];
f = n_remove(&lp, p);
if (f)
cond *= n_pow(p, G->exponents[k] - f);
else
cond *= G->primepowers[k];
}
}
return cond;
}

View file

@ -0,0 +1,35 @@
/*=============================================================================
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"
void
acb_dirichlet_conrey_pow(acb_dirichlet_conrey_t c, const acb_dirichlet_group_t G, const acb_dirichlet_conrey_t a, ulong n)
{
ulong k;
for (k = 0; k < G->num ; k++)
c->log[k] = (a->log[k] * n) % G->phi[k];
c->n = nmod_pow_ui(a->n, n, G->mod);
}

View file

@ -45,6 +45,52 @@ nmod_order_precomp(ulong a, nmod_t mod, ulong expo, n_factor_t fac)
return order;
}
static ulong
n_conductor(ulong q, ulong a)
{
slong k;
ulong ap, cond;
nmod_t pe;
n_factor_t fac;
n_factor_init(&fac);
n_factor(&fac, q, 1);
cond = 1;
for (k = 0; k < fac.num; k++)
{
ulong p, e;
p = fac.p[k];
e = fac.exp[k];
nmod_init(&pe, n_pow(p, e));
ap = a % pe.n;
if (ap == 1)
continue;
if (p == 2)
{
cond = 4;
if (a % 4 == 3)
ap = pe.n - ap;
}
else
{
cond *= p;
ap = nmod_pow_ui(ap, p - 1, pe);
}
while (ap != 1)
{
cond *= p;
ap = nmod_pow_ui(ap, p, pe);
}
}
return cond;
}
int main()
{
slong iter, bits;
@ -78,7 +124,7 @@ int main()
for (iter2 = 0; iter2 < 50; iter2++)
{
ulong m, n;
ulong order, chim1, pairing;
ulong order, chim1, pairing, cond;
do
m = n_randint(state, q);
@ -97,6 +143,17 @@ int main()
abort();
}
cond = n_conductor(G->q, m);
if (cond != acb_dirichlet_char_conductor(G, chi))
{
flint_printf("FAIL: conductor\n\n");
flint_printf("q = %wu\n\n", q);
flint_printf("m = %wu\n\n", m);
flint_printf("conductor(m) = %wu\n\n", cond);
flint_printf("chi->conductor = %wu\n\n", acb_dirichlet_char_conductor(G, chi));
abort();
}
chim1 = acb_dirichlet_ui_chi(G, chi, q - 1);
if (acb_dirichlet_char_parity(chi) != (chim1 != 0))
{