int main(int argc, string argv[]) { stream outstr = NULL; int nmodel; real tzero = 0.0; initparam(argv, defv); layout_body(bodyfields, Precision, NDIM); npol = getdparam("n"); mpol = getdparam("m"); nbody = getiparam("nbody"); btab = (bodyptr) allocate(nbody * SizeofBody); init_random(getiparam("seed")); nmodel = getiparam("nmodel"); if (! ((npol == 1.0 && mpol == -1.0) || (npol == 0.5 && mpol == -0.5))) polysolve(getdparam("hstep"), getbparam("listmodel")); if (! strnull(getparam("out"))) { outstr = stropen(getparam("out"), "w"); put_history(outstr); } while (--nmodel >= 0) { if (npol == 1.0 && mpol == -1.0) polymodel1(); else if (npol == 0.5 && mpol == -0.5) polymodel2(); else polymodel(); if (getbparam("besort")) qsort(btab, nbody, SizeofBody, berank); if (getbparam("zerocm")) snapcenter(btab, nbody, MassField.offset); if (outstr != NULL) put_snap(outstr, &btab, &nbody, &tzero, bodyfields); fflush(outstr); } return (0); }
int Solve_Polynomial(int n, DBL *c0, DBL *r, int sturm, DBL epsilon) { int roots, i; DBL *c; Increase_Counter(stats[Polynomials_Tested]); roots = 0; /* * Determine the "real" order of the polynomial, i.e. * eliminate small leading coefficients. */ i = 0; while ((fabs(c0[i]) < SMALL_ENOUGH) && (i < n)) { i++; } n -= i; c = &c0[i]; switch (n) { case 0: break; case 1: /* Solve linear polynomial. */ if (c[0] != 0.0) { r[roots++] = -c[1] / c[0]; } break; case 2: /* Solve quadratic polynomial. */ roots = solve_quadratic(c, r); break; case 3: /* Root elimination? */ if (epsilon > 0.0) { if ((c[2] != 0.0) && (fabs(c[3]/c[2]) < epsilon)) { Increase_Counter(stats[Roots_Eliminated]); roots = solve_quadratic(c, r); break; } } /* Solve cubic polynomial. */ if (sturm) { roots = polysolve(3, c, r); } else { roots = solve_cubic(c, r); } break; case 4: /* Root elimination? */ if (epsilon > 0.0) { if ((c[3] != 0.0) && (fabs(c[4]/c[3]) < epsilon)) { Increase_Counter(stats[Roots_Eliminated]); if (sturm) { roots = polysolve(3, c, r); } else { roots = solve_cubic(c, r); } break; } } /* Test for difficult coeffs. */ if (difficult_coeffs(4, c)) { sturm = true; } /* Solve quartic polynomial. */ if (sturm) { roots = polysolve(4, c, r); } else { roots = solve_quartic(c, r); } break; default: if (epsilon > 0.0) { if ((c[n-1] != 0.0) && (fabs(c[n]/c[n-1]) < epsilon)) { Increase_Counter(stats[Roots_Eliminated]); roots = polysolve(n-1, c, r); } } /* Solve n-th order polynomial. */ roots = polysolve(n, c, r); break; } return(roots); }
/* * Full implementation of the three error correcting Peterson decoder. For * t<6, it is faster than Massey - Berlekamp. It is also somewhat more * intuitive. */ extern void ecc_decode(uint8_t code[ECC_CAPACITY], uint8_t mesg[ECC_CAPACITY], int *errcode) { REVERSE(code, ECC_CAPACITY); uint8_t syn[ECC_OFFSET + 1], deter, z[4], e0, e1, e2, n0, n1, n2, w0, w1, w2, x0, x[3]; int sols; *errcode = 0; /* * First, get the message out of the code, so that even if we can't correct * it, we return an estimate. */ for (int i = 0; i < ECC_PAYLOAD; i++) mesg[i] = code[(ECC_CAPACITY - 1) - i]; syndrome(code, syn); if (syn[0] == 0) return; /* * We now know we have at least one error. If there are no errors detected, * we assume that something funny is going on, and so return with errcode 4, * else pass the number of errors back via errcode. */ errnum(syn, &deter, errcode); if (*errcode == 4) return; /* Having obtained the syndrome, the number of errors, and the determinant, * we now proceed to correct the block. If we do not find exactly the * number of solutions equal to the number of errors, we have exceeded our * error capacity, and return with the block uncorrected, and errcode 4. */ switch (*errcode) { case 1: x0 = GF_MUL(syn[2], GF_INV(syn[1])); w0 = GF_MUL(GF_EXP(syn[1], 2), GF_INV(syn[2])); if (v2e[x0] > 5) mesg[(ECC_CAPACITY - 1) - v2e[x0]] = GF_ADD(mesg[(ECC_CAPACITY - 1) - v2e[x0]], w0); return; case 2: z[0] = GF_MUL(GF_ADD(GF_MUL(syn[1], syn[3]), GF_EXP(syn[2], 2)), GF_INV(deter)); z[1] = GF_MUL(GF_ADD(GF_MUL(syn[2], syn[3]), GF_MUL(syn[1], syn[4])), GF_INV(deter)); z[2] = 1; z[3] = 0; polysolve(z, x, &sols); if (sols != 2) { *errcode = 4; return; } w0 = GF_MUL(z[0], syn[1]); w1 = GF_ADD(GF_MUL(z[0], syn[2]), GF_MUL(z[1], syn[1])); n0 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[0])]; n1 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[1])]; e0 = GF_MUL(GF_ADD(w0, GF_MUL(w1, x[0])), GF_INV(z[1])); e1 = GF_MUL(GF_ADD(w0, GF_MUL(w1, x[1])), GF_INV(z[1])); if (n0 < ECC_PAYLOAD) mesg[n0] = GF_ADD(mesg[n0], e0); if (n1 < ECC_PAYLOAD) mesg[n1] = GF_ADD(mesg[n1], e1); return; case 3: z[3] = 1; z[2] = GF_MUL(syn[1], GF_MUL(syn[4], syn[6])); z[2] = GF_ADD(z[2], GF_MUL(syn[1], GF_MUL(syn[5], syn[5]))); z[2] = GF_ADD(z[2], GF_MUL(syn[5], GF_MUL(syn[3], syn[3]))); z[2] = GF_ADD(z[2], GF_MUL(syn[3], GF_MUL(syn[4], syn[4]))); z[2] = GF_ADD(z[2], GF_MUL(syn[2], GF_MUL(syn[5], syn[4]))); z[2] = GF_ADD(z[2], GF_MUL(syn[2], GF_MUL(syn[3], syn[6]))); z[2] = GF_MUL(z[2], GF_INV(deter)); z[1] = GF_MUL(syn[1], GF_MUL(syn[3], syn[6])); z[1] = GF_ADD(z[1], GF_MUL(syn[1], GF_MUL(syn[5], syn[4]))); z[1] = GF_ADD(z[1], GF_MUL(syn[4], GF_MUL(syn[3], syn[3]))); z[1] = GF_ADD(z[1], GF_MUL(syn[2], GF_MUL(syn[4], syn[4]))); z[1] = GF_ADD(z[1], GF_MUL(syn[2], GF_MUL(syn[3], syn[5]))); z[1] = GF_ADD(z[1], GF_MUL(syn[2], GF_MUL(syn[2], syn[6]))); z[1] = GF_MUL(z[1], GF_INV(deter)); z[0] = GF_MUL(syn[2], GF_MUL(syn[3], syn[4])); z[0] = GF_ADD(z[0], GF_MUL(syn[3], GF_MUL(syn[2], syn[4]))); z[0] = GF_ADD(z[0], GF_MUL(syn[3], GF_MUL(syn[5], syn[1]))); z[0] = GF_ADD(z[0], GF_MUL(syn[4], GF_MUL(syn[4], syn[1]))); z[0] = GF_ADD(z[0], GF_MUL(syn[3], GF_MUL(syn[3], syn[3]))); z[0] = GF_ADD(z[0], GF_MUL(syn[2], GF_MUL(syn[2], syn[5]))); z[0] = GF_MUL(z[0], GF_INV(deter)); polysolve (z, x, &sols); if (sols != 3) { *errcode = 4; return; } w0 = GF_MUL(z[0], syn[1]); w1 = GF_ADD(GF_MUL(z[0], syn[2]), GF_MUL(z[1], syn[1])); w2 = GF_ADD(GF_MUL(z[0], syn[3]), GF_ADD(GF_MUL(z[1], syn[2]), GF_MUL(z[2], syn[1]))); n0 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[0])]; n1 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[1])]; n2 = (ECC_CAPACITY - 1) - v2e[GF_INV(x[2])]; e0 = GF_ADD(w0, GF_ADD(GF_MUL(w1, x[0]), GF_MUL(w2, GF_EXP(x[0], 2)))); e0 = GF_MUL(e0, GF_INV(GF_ADD(z[1], GF_EXP(x[0], 2)))); e1 = GF_ADD(w0, GF_ADD(GF_MUL(w1, x[1]), GF_MUL(w2, GF_EXP(x[1], 2)))); e1 = GF_MUL(e1, GF_INV(GF_ADD(z[1], GF_EXP(x[1], 2)))); e2 = GF_ADD(w0, GF_ADD(GF_MUL(w1, x[2]), GF_MUL(w2, GF_EXP(x[2], 2)))); e2 = GF_MUL(e2, GF_INV(GF_ADD(z[1], GF_EXP(x[2], 2)))); if (n0 < ECC_PAYLOAD) mesg[n0] = GF_ADD(mesg[n0], e0); if (n1 < ECC_PAYLOAD) mesg[n1] = GF_ADD(mesg[n1], e1); if (n2 < ECC_PAYLOAD) mesg[n2] = GF_ADD(mesg[n2], e2); return; } }