int main() { DUPFF f, g, cf, cg, h; f = DUPFFnew(1); f->coeffs[1] = 1; f->deg = 1; g = DUPFFnew(2); g->coeffs[2] = 1; g->deg = 2; h = DUPFFexgcd(&cf, &cg, f, g); h = h; return 0; }
DUPFF DUPFFexgcd(DUPFF *fcofac, DUPFF *gcofac, const DUPFF f, const DUPFF g) { DUPFF u, v, uf, ug, vf, vg; FFelem q, lcu, lcvrecip, p; int df, dg, du, dv; if (DUPFFdeg(f) < DUPFFdeg(g)) return DUPFFexgcd(gcofac, fcofac, g, f); if (DUPFFdeg(f) != 2 || DUPFFdeg(g) != 1) abort(); if (f->coeffs[0] == 0) return f; p = 2; df = DUPFFdeg(f); if (df < 0) df = 0; /* both inputs are zero */ dg = DUPFFdeg(g); if (dg < 0) dg = 0; /* one input is zero */ u = DUPFFcopy(f); v = DUPFFcopy(g); uf = DUPFFnew(dg); uf->coeffs[0] = 1; uf->deg = 0; ug = DUPFFnew(df); vf = DUPFFnew(dg); vg = DUPFFnew(df); vg->coeffs[0] = 1; vg->deg = 0; while (DUPFFdeg(v) > 0) { dv = DUPFFdeg(v); lcvrecip = FFmul(1, v->coeffs[dv]); while (DUPFFdeg(u) >= dv) { du = DUPFFdeg(u); lcu = u->coeffs[du]; q = FFmul(lcu, lcvrecip); DUPFFshift_add(u, v, du-dv, p-q); DUPFFshift_add(uf, vf, du-dv, p-q); DUPFFshift_add(ug, vg, du-dv, p-q); } DUPFFswap(u, v); DUPFFswap(uf, vf); DUPFFswap(ug, vg); } if (DUPFFdeg(v) == 0) { DUPFFswap(u, v); DUPFFswap(uf, vf); DUPFFswap(ug, vg); } DUPFFfree(vf); DUPFFfree(vg); DUPFFfree(v); *fcofac = uf; *gcofac = ug; return u; }
DUPFF DMPZ_to_DUPFF(DMPZ f, int var, int *substitution) { FFelem p = CurrentFF.prime; int df, d, c, i; DUPFF ans; DMPZ iter; df = DMPZdeg(f, var); ans = DUPFFnew(df); for(i=0; i<=df;i++) ans->coeffs[i] = 0; for(iter=f;iter;iter = iter->next) { d = iter->exps[var]; c = mpz_fdiv_ui(iter->coeff, p); for(i=0; c!=0 && i<NVARS;i++) if (i != var) c = FFmul(c, FFpow(substitution[i], iter->exps[i])); ans->coeffs[d] += c; if (ans->coeffs[d] >= p) ans->coeffs[d] -= p; } for(i=df;i>=0;i--) if (ans->coeffs[i] != 0) break; ans->deg = i; return ans; }