X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a..HEAD:/math/limlee.c diff --git a/math/limlee.c b/math/limlee.c index b20965a9..c99ba7bd 100644 --- a/math/limlee.c +++ b/math/limlee.c @@ -114,13 +114,10 @@ static void llgen(limlee_factor *f, unsigned pl, limlee_stepctx *l) rabin r; mp *p; -again: p = mprand(l->newp, pl, l->r, 1); pf.step = 2; - p = pgen(l->d.buf, p, p, l->iev, l->iec, 0, pgen_filter, &pf, + p = pgen(l->u.s.name, p, p, l->iev, l->iec, 0, pgen_filter, &pf, rabin_iters(pl), pgen_test, &r); - if (!p) - goto again; f->p = p; } @@ -146,18 +143,12 @@ static const limlee_primeops primeops_simple = { llgen, llfree }; static int init(pgen_event *ev, limlee_stepctx *l) { size_t i; - unsigned qql; /* --- First of all, decide on a number of factors to make --- */ l->nf = l->pl / l->ql; - qql = l->pl % l->ql; - if (!l->nf) - return (PGEN_ABORT); - else if (qql && l->nf > 1) { - l->nf--; - qql += l->ql; - } + if (l->nf < 2) return (PGEN_ABORT); + l->nf--; /* --- Now decide on how many primes I'll actually generate --- * * @@ -180,20 +171,14 @@ static int init(pgen_event *ev, limlee_stepctx *l) /* --- Other bits of initialization --- */ l->seq = 0; - dstr_create(&l->d); if (!l->pops) { l->pops = &primeops_simple; l->pc = 0; } - /* --- Find a big prime --- */ + /* --- Find a big prime later --- */ - if (!qql) - l->qq.p = 0; - else { - dstr_putf(&l->d, "%s*", ev->name); - l->pops->pgen(&l->qq, qql, l); - } + l->qq.p = 0; return (PGEN_TRY); } @@ -211,8 +196,11 @@ static int init(pgen_event *ev, limlee_stepctx *l) static int next(int rq, pgen_event *ev, limlee_stepctx *l) { - mp *p; + dstr d = DSTR_INIT; + mp *p = 0; int rc; + int dist; + unsigned nb; mp_drop(ev->m); @@ -230,32 +218,68 @@ static int next(int rq, pgen_event *ev, limlee_stepctx *l) } rq = PGEN_TRY; /* For next time through */ + /* --- If the large factor is performing badly, make a new one --- */ + + if (l->qq.p) { + dist = l->u.s.disp < 0 ? -l->u.s.disp : l->u.s.disp; + if (dist && dist > l->u.s.steps/3) { + l->pops->pfree(&l->qq, l); + l->qq.p = 0; + } + } + /* --- Gather up some factors --- */ - if (l->qq.p) - mpmul_add(&mm, l->qq.p); + if (l->qq.p) mpmul_add(&mm, l->qq.p); for (i = 0; i < l->poolsz; i++) { if (!l->c[i]) continue; if (!l->v[i].p) { - DRESET(&l->d); - dstr_putf(&l->d, "%s_%lu", ev->name, l->seq++); + DRESET(&d); + dstr_putf(&d, "%s_%lu", ev->name, l->seq++); + l->u.s.name = d.buf; l->pops->pgen(&l->v[i], l->ql, l); + if (!l->v[i].p) + { mp_drop(mpmul_done(&mm)); rc = PGEN_ABORT; goto end; } } mpmul_add(&mm, l->v[i].p); } - /* --- Check it for small factors --- */ + /* --- Check on the large factor --- */ p = mpmul_done(&mm); + if (!l->qq.p) { + DRESET(&d); + dstr_putf(&d, "%s*_%lu", ev->name, l->seq++); + l->u.s.name = d.buf; + l->pops->pgen(&l->qq, l->pl - mp_bits(p), l); + if (!l->qq.p) { MP_DROP(p); p = 0; rc = PGEN_ABORT; break; } + l->u.s.steps = l->u.s.disp = 0; + p = mp_mul(p, p, l->qq.p); + } p = mp_lsl(p, p, 1); p->v[0] |= 1; + + nb = mp_bits(p); + l->u.s.steps++; + if (nb < l->pl) { + l->u.s.disp--; + continue; + } else if (nb > l->pl) { + l->u.s.disp++; + continue; + } + + /* --- Check it for small factors --- */ + if ((rc = pfilt_smallfactor(p)) != PGEN_FAIL) break; - mp_drop(p); + MP_DROP(p); p = 0; } +end: ev->m = p; + DDESTROY(&d); return (rc); } @@ -305,7 +329,6 @@ static int done(pgen_event *ev, limlee_stepctx *l) /* --- Free other resources --- */ xfree(l->c); - dstr_destroy(&l->d); /* --- Done --- */ @@ -367,6 +390,8 @@ mp *limlee(const char *name, mp *d, mp *newp, { limlee_stepctx l; rabin rr; + mp **v; + size_t i; l.f = 0; if (f) l.f |= LIMLEE_KEEPFACTORS; l.newp = newp; @@ -379,15 +404,18 @@ mp *limlee(const char *name, mp *d, mp *newp, d = pgen(name, d, 0, oev, oec, on, limlee_step, &l, rabin_iters(pl), pgen_test, &rr); - if (d && f) { - mp **v; - size_t i; - v = xmalloc(l.nf * sizeof(mp *)); - for (i = 0; i < l.nf; i++) - v[i] = l.v[i].p; - xfree(l.v); - *f = v; - *nf = l.nf; + if (f) { + if (!d) { + for (i = 0; i < l.nf; i++) + if (l.v[i].p) llfree(&l.v[i], &l); + } else { + v = xmalloc(l.nf * sizeof(mp *)); + for (i = 0; i < l.nf; i++) + v[i] = l.v[i].p; + xfree(l.v); + *f = v; + *nf = l.nf; + } } return (d);