#include #include #include #include "opt.h" #define Debug 1 #define Static static #define SKIPTIME 100 /* print interval for debugging */ static int nvar; static dbl (*objective)(); static dbl *(*gradient)(); static dbl *xtmp; static dbl *gtmp; static dbl *h, *dl, *gm; static dbl *dg, *gd; static dbl *matq; static dbl *hnew; static dbl *xnew, *grad, *gradnew, *d; static void initialize() { xtmp = alloc(dbl, nvar); gtmp = alloc(dbl, nvar); h = alloc(dbl, nvar*nvar); dl = alloc(dbl, nvar); gm = alloc(dbl, nvar); dg = alloc(dbl, nvar); gd = alloc(dbl, nvar); matq = alloc(dbl, nvar*nvar); hnew = alloc(dbl, nvar*nvar); xnew = alloc(dbl, nvar); grad = alloc(dbl, nvar); gradnew = alloc(dbl, nvar); d = alloc(dbl, nvar); } static void terminate() { free(xtmp); free(gtmp); free(h); free(dl); free(gm); free(dg); free(gd); free(matq); free(hnew); free(xnew); free(grad); free(gradnew); free(d); } Static dbl theta_1(xinit, d, finit, p1, ro) dbl *xinit; dbl *d; dbl finit, p1, ro; { int i; for (i=0; i 1 if (k % 1 == 0) { fprintf(stderr, "%d: t1=%lg t2=%lg\n", k, t1, t2); } #endif if (t1 <= 0) { if (t2 >= 0) { return(ro); } else { ro += dro; } } else { a = ro - dro; b = ro; break; } } if (k == search_times) { return(0.00); } for (;;) { #if Debug > 1 fprintf(stderr, "a=%lg b=%lg\n", a, b); #endif ro = (a + b) / 2.00; if (b - a < search_eps) { return(ro); } t1 = theta_1(xinit, d, finit, p1, ro); t2 = theta_2(xinit, d, p2, ro); #if Debug > 1 fprintf(stderr, "t1=%lg t2=%lg\n", t1, t2); #endif if (t1 <= 0 && t2 >= 0) { return(ro); } if (t1 > 0) { b = ro; } else { a = ro; } } } #if 0 Static void update(dbl *h, dbl *dl, dbl *gm) { int i, j, k, l; dbl sum; if ((sum = vectorvector(nvar, dl, gm)) == 0.00) { return; } for (i=0; i= MAXFLOAT) { fprintf(stderr, "overflow\n"); stat = failure; break; /* return(failure); */ } #if Debug if (k % SKIPTIME == 0) { fprintf(stderr, "k = %d f = %lg\n", k, finit); /* vectorfprint(stderr, nvar, xinit); */ } #endif if (fnew - finit < eps) { stat = success; break; /* *fopt = finit; */ /* return(success); */ } (*drv)(nvar, xinit, grad); matrixvector(nvar, nvar, d, h, grad); scalarvector(nvar, d, -1.00, d); sum = vectorvector(nvar, grad, d); if (sum >= 0) { matrixunit(nvar, h); matrixvector(nvar, nvar, d, h, grad); scalarvector(nvar, d, -1.00, d); } al = Wolfe_line_search(xinit, d); if (al == 0.00) { fprintf(stderr, "bfgs.c: alpha = %lf\n", al); break; } scalarvector(nvar, dl, al, d); vectoradd(nvar, xnew, xinit, dl); (*drv)(nvar, xnew, gradnew); vectorsub(nvar, gm, gradnew, grad); update(h, dl, gm); vectorcopy(nvar, xinit, xnew); } if (k >= timeout) fprintf(stderr, "timeout\n"); /* fprintf(stderr, "***** end *****\n"); */ *fopt = finit; terminate(); return (stat); /* *fopt = finit; */ /* return(failure); */ }