double agcep(double x, double *c, const int m, const int stage, const double lambda, const double step, const double tau, const double eps) { int i; static double *eg = NULL, *ep, *d, gg = 1.0, ee = 1.0, tx; static int size; double mu, ll; int expected_size = 2 * (m + 1) + m * stage; if (eg == NULL) { eg = dgetmem(expected_size); ep = eg + m + 1; d = ep + m + 1; size = expected_size; } if (expected_size > size) { free(eg); eg = dgetmem(expected_size); ep = eg + m + 1; d = ep + m + 1; size = expected_size; } ll = 1.0 - lambda; eg[m] = d[stage * m - 1]; x = iglsadf1(x, c, m, stage, d); movem(d + (stage - 1) * m, eg, sizeof(*d), m); gg = lambda * gg + ll * eg[0] * eg[0]; gg = (gg < eps) ? eps : gg; mu = step / (double) m / gg; tx = 2 * (1.0 - tau) * x; for (i = 1; i <= m; i++) { ep[i] = tau * ep[i] - tx * eg[i]; c[i] -= mu * ep[i]; } ee = lambda * ee + ll * x * x; c[0] = sqrt(ee); return (x); }
int main(int argc, char **argv) { int m = ORDER, period = PERIOD, stage = STAGE, i, j; FILE *fp = stdin, *fpe = NULL; Boolean ave = AVERAGE, norm = NORM; double lambda = LAMBDA, step = STEP, eps = EPS, *c, *cc, *eg, *ep, *d, *avec, tau = TAU, x, ee, ll, gg, mu, gamma, tt, ttx; if ((cmnd = strrchr(argv[0], '/')) == NULL) cmnd = argv[0]; else cmnd++; while (--argc) if (**++argv == '-') { switch (*(*argv + 1)) { case 'l': lambda = atof(*++argv); --argc; break; case 't': tau = atof(*++argv); --argc; break; case 'k': step = atof(*++argv); --argc; break; case 'm': m = atoi(*++argv); --argc; break; case 'c': stage = atoi(*++argv); --argc; break; case 'p': period = atoi(*++argv); --argc; break; case 's': ave = 1 - ave; break; case 'n': norm = 1 - norm; break; case 'e': eps = atof(*++argv); --argc; break; case 'h': usage(0); default: fprintf(stderr, "%s : Invalid option '%c'!\n", cmnd, *(*argv + 1)); usage(1); } } else fpe = getfp(*argv, "wb"); if (stage == 0) { fprintf(stderr, "%s : gamma should not equal to 0!\n", cmnd); usage(1); } gamma = -1.0 / (double) stage; c = dgetmem(5 * (m + 1) + m * stage); cc = c + m + 1; eg = cc + m + 1; ep = eg + m + 1; avec = ep + m + 1; d = avec + m + 1; j = period; ll = 1.0 - lambda; gg = 1.0; ee = 1.0; step /= (double) m; tt = 2 * (1.0 - tau); while (freadf(&x, sizeof(x), 1, fp) == 1) { eg[m] = d[stage * m - 1]; x = iglsadf1(x, c, m, stage, d); movem(d + (stage - 1) * m, eg, sizeof(*d), m); gg = lambda * gg + ll * eg[0] * eg[0]; gg = (gg < eps) ? eps : gg; mu = step / gg; ttx = tt * x; for (i = 1; i <= m; i++) { ep[i] = tau * ep[i] - ttx * eg[i]; c[i] -= mu * ep[i]; } ee = lambda * ee + ll * x * x; c[0] = sqrt(ee); if (ave) for (i = 0; i <= m; i++) avec[i] += c[i]; if (fpe != NULL) fwritef(&x, sizeof(x), 1, fpe); if (--j == 0) { j = period; if (ave) { for (i = 0; i <= m; i++) avec[i] /= period; if (!norm) ignorm(avec, cc, m, gamma); fwritef(cc, sizeof(*cc), m + 1, stdout); fillz(avec, sizeof(*avec), m + 1); } else if (!norm) { ignorm(c, cc, m, gamma); fwritef(cc, sizeof(*cc), m + 1, stdout); } else fwritef(c, sizeof(*c), m + 1, stdout); } } return (0); }