/* Copyright (C) 2016 Pascal Molin This file is part of Arb. Arb is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License (LGPL) as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See . */ #include "dlog.h" #include #define vbs 0 /* TODO: tune the limit dlog -> index calculus */ void dlog_vec_sieve_precomp(ulong *v, ulong nv, dlog_precomp_t pre, ulong a, ulong va, nmod_t mod, ulong na, nmod_t order) { ulong smooth = 0, sievecount = 0, logcount = 0, missed = 0; ulong logcost; #if 0 ulong limcount; #endif ulong k, p, pmax, logm1; n_primes_t iter; ulong X, aX, vaX; dlog_vec_fill(v, nv, DLOG_NOT_FOUND); v[1] = 0; logm1 = (na % 2) ? 0 : nmod_mul(na / 2, va, order); /* discrete log on first primes, then sieve */ pmax = (nv < mod.n) ? nv : mod.n; logcost = pre->cost; #if 0 if (logcost < 15) { /* p1 = pmax; */ limcount = mod.n; } else { limcount = ceil(pow((double)mod.n,1./2.3) * 40 / logcost); } #endif /* take big power of gen */ X = n_nextprime(3 * na / 2, 0) % na; aX = nmod_pow_ui(a, X, mod); vaX = nmod_mul(va, X % order.n, order); n_primes_init(iter); while ((p = n_primes_next(iter)) < pmax) { double cost; ulong m, vp; if (mod.n % p == 0) continue; /* won't be attained another time */ cost = log(mod.n)/log(p); cost = pow(cost,cost); sievecount++; /* if (p < p1 || (wp = logp_sieve(w, nv, p, mod.n, logm1, order, logcost)) == NOT_FOUND) */ /* if (smooth < limcount || (wp = logp_sieve_factor(w, nv, p, mod.n, a, na, va, logm1, order, logcost)) == NOT_FOUND)*/ if (logcost < cost || (vp = dlog_vec_pindex_factorgcd(v, nv, p, mod, aX, na, vaX, logm1, order, cost)) == DLOG_NOT_FOUND) { if (logcost < cost) sievecount--; else missed++; logcount++; vp = nmod_mul(dlog_precomp(pre, p), va, order); } for (k = p, m = 1; k < nv; k += p, m++) { if (v[m] == DLOG_NOT_FOUND) continue; smooth++; v[k] = nmod_add(v[m], vp, order); } } #if vbs if (missed) flint_printf("[sieve: got %wu / %wu, n = %wu, cost %wu, logs %wu, sieve %wu missed %wu]\n", smooth, limcount, mod.n, logcost, logcount, sievecount, missed); #endif n_primes_clear(iter); for (k = mod.n + 1; k < nv; k++) v[k] = v[k - mod.n]; }