1 /*
2  *  gretl -- Gnu Regression, Econometrics and Time-series Library
3  *  Copyright (C) 2001 Allin Cottrell and Riccardo "Jack" Lucchetti
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 /* The BFGS and Newton optimizers plus the fdjac Jacobian function */
21 
22 #include "libgretl.h"
23 #include "gretl_bfgs.h"
24 #include "libset.h"
25 #include "matrix_extra.h"
26 #include "usermat.h"
27 #include "uservar.h"
28 #include "gretl_func.h"
29 
30 #include "../../minpack/minpack.h"
31 #include <float.h>
32 #include <errno.h>
33 
34 #define BFGS_DEBUG 0
35 
36 #define BFGS_MAXITER_DEFAULT 600
37 
BFGS_defaults(int * maxit,double * tol,int ci)38 void BFGS_defaults (int *maxit, double *tol, int ci)
39 {
40     *maxit = libset_get_int(BFGS_MAXITER);
41     *tol = libset_get_user_tolerance(BFGS_TOLER);
42 
43     if (ci != MLE && ci != GMM && *maxit <= 0) {
44 	*maxit = 1000;
45     }
46 
47     if (ci == PROBIT || ci == INTREG || ci == ARMA ||
48 	ci == NEGBIN || ci == DURATION) {
49 	if (na(*tol)) {
50 	    *tol = 1.0e-12;
51 	}
52     } else if (ci == TOBIT) {
53 	if (na(*tol)) {
54 	    *tol = 1.0e-10; /* calibrated against Wm Greene */
55 	}
56     } else if (ci == HECKIT) {
57 	if (na(*tol)) {
58 	    *tol = 1.0e-09;
59 	}
60     } else if (ci == GARCH) {
61 	if (na(*tol)) {
62 	    *tol = 1.0e-13;
63 	}
64     } else if (ci == MLE || ci == GMM) {
65 	if (*maxit <= 0) {
66 	    *maxit = BFGS_MAXITER_DEFAULT;
67 	}
68 	if (na(*tol)) {
69 	    *tol = libset_get_double(BFGS_TOLER);
70 	}
71     }
72 }
73 
free_triangular_array(double ** m,int n)74 static void free_triangular_array (double **m, int n)
75 {
76     if (m != NULL) {
77 	int i;
78 
79 	for (i=0; i<n; i++) {
80 	    free(m[i]);
81 	}
82 	free(m);
83     }
84 }
85 
triangular_array_new(int n)86 static double **triangular_array_new (int n)
87 {
88     double **m = malloc(n * sizeof *m);
89     int i;
90 
91     if (m != NULL) {
92 	for (i=0; i<n; i++) {
93 	    m[i] = NULL;
94 	}
95 	for (i=0; i<n; i++) {
96 	    m[i] = malloc((i + 1) * sizeof **m);
97 	    if (m[i] == NULL) {
98 		free_triangular_array(m, n);
99 		return NULL;
100 	    }
101 	}
102     }
103 
104     return m;
105 }
106 
107 /* State variable set when doing hessian_from_score(), to alert
108    the gradient function to the fact that the parameters will
109    be changing and in general NOT the same as in the last call
110    to the loglikelihood function.
111 */
112 static int doing_hess_score;
113 
114 /* accessor for the above */
hess_score_on(void)115 int hess_score_on (void)
116 {
117     return doing_hess_score;
118 }
119 
120 /**
121  * hessian_from_score:
122  * @b: array of k parameter estimates.
123  * @H: k x k matrix to receive the (negative) Hessian.
124  * @gradfunc: function to compute gradient.
125  * @cfunc: function to compute criterion (or NULL, see below).
126  * @data: data to be passed to the @gradfunc callback.
127  *
128  * Uses the score function (@gradfunc) is to construct a
129  * numerical approximation to the Hessian. This is primarily
130  * intended for building a covariance matrix at convergence;
131  * note that it may not work well at an arbitrary point in
132  * the parameter space.
133  *
134  * Note that the only use of @cfunc within this function is
135  * as an argument to be passed to @gradfunc. It is therefore
136  * OK to pass NULL for @cfunc provided that @gradfunc does not
137  * use its 4th argument, which corresponds to the BFGS_CRIT_FUNC
138  * parameter.
139  *
140  * Returns: 0 on successful completion, non-zero error code
141  * on error.
142  */
143 
hessian_from_score(double * b,gretl_matrix * H,BFGS_GRAD_FUNC gradfunc,BFGS_CRIT_FUNC cfunc,void * data)144 int hessian_from_score (double *b, gretl_matrix *H,
145 			BFGS_GRAD_FUNC gradfunc,
146 			BFGS_CRIT_FUNC cfunc,
147 			void *data)
148 {
149     double *g, *splus, *sminus, *splus2, *sminus2;
150     double x, den, b0, eps = 1.0e-05;
151     int n = gretl_matrix_rows(H);
152     int extra_precision = 0;
153     int i, j, err = 0;
154 
155     char *s = getenv("H_EXTRA");
156 
157     if (s != NULL && *s != '\0') {
158 	extra_precision = 1;
159 	fprintf(stderr, "hessian_from_score: using extra precision\n");
160     }
161 
162     if (extra_precision) {
163 	splus = malloc(5 * n * sizeof *splus);
164 	splus2 = splus + n;
165 	sminus = splus2 + n;
166 	sminus2 = sminus + n;
167 	g = sminus2 + n;
168 	den = 12*eps;
169     } else {
170 	splus = malloc(3 * n * sizeof *splus);
171 	sminus = splus + n;
172 	g = sminus + n;
173 	splus2 = sminus2 = NULL;
174 	den = 2*eps;
175     }
176 
177     if (splus == NULL) {
178 	return E_ALLOC;
179     }
180 
181     doing_hess_score = 1;
182 
183     for (i=0; i<n; i++) {
184 	b0 = b[i];
185 	b[i] = b0 + eps;
186 	err = gradfunc(b, g, n, cfunc, data);
187 	if (err) goto restore;
188 	for (j=0; j<n; j++) {
189 	    splus[j] = g[j];
190 	}
191 	b[i] = b0 - eps;
192 	err = gradfunc(b, g, n, cfunc, data);
193 	if (err) goto restore;
194 	for (j=0; j<n; j++) {
195 	    sminus[j] = g[j];
196 	}
197 	if (extra_precision) {
198 	    b[i] = b0 - 2*eps;
199 	    err = gradfunc(b, g, n, cfunc, data);
200 	    if (err) goto restore;
201 	    for (j=0; j<n; j++) {
202 		sminus2[j] = g[j];
203 	    }
204 	    b[i] = b0 + 2*eps;
205 	    err = gradfunc(b, g, n, cfunc, data);
206 	    if (err) goto restore;
207 	    for (j=0; j<n; j++) {
208 		splus2[j] = g[j];
209 	    }
210 	}
211     restore:
212 	b[i] = b0;
213 	if (err) {
214 	    break;
215 	}
216 	for (j=0; j<n; j++) {
217 	    if (extra_precision) {
218 		x = -(splus2[j] - sminus2[j]) + 8*(splus[j] - sminus[j]);
219 	    } else {
220 		x = splus[j] - sminus[j];
221 	    }
222 	    gretl_matrix_set(H, i, j, -x / den);
223 	}
224     }
225 
226     doing_hess_score = 0;
227 
228     if (!err) {
229 	gretl_matrix_xtr_symmetric(H);
230     }
231 
232     free(splus);
233 
234     return err;
235 }
236 
237 /**
238  * hessian_inverse_from_score:
239  * @b: array of parameter estimates.
240  * @n: the number of elements in @b.
241  * @gradfunc: function to compute gradient.
242  * @cfunc: function to compute criterion.
243  * @data: data to be passed to the @gradfunc callback.
244  * @err: location to receive error code.
245  *
246  * A wrapper for hessian_from_score() which takes care of
247  * (a) allocation of the Hessian and (b) inversion.
248  *
249  * Returns: the inverse of the (negative) Hessian on successful
250  * completion, NULL on error.
251  */
252 
hessian_inverse_from_score(double * b,int n,BFGS_GRAD_FUNC gradfunc,BFGS_CRIT_FUNC cfunc,void * data,int * err)253 gretl_matrix *hessian_inverse_from_score (double *b, int n,
254 					  BFGS_GRAD_FUNC gradfunc,
255 					  BFGS_CRIT_FUNC cfunc,
256 					  void *data, int *err)
257 {
258     gretl_matrix *H = gretl_zero_matrix_new(n, n);
259 
260     if (H == NULL) {
261 	*err = E_ALLOC;
262     } else {
263 	*err = hessian_from_score(b, H, gradfunc, cfunc, data);
264     }
265 
266     if (!*err) {
267 	*err = gretl_invert_symmetric_matrix(H);
268 	if (*err) {
269 	    fprintf(stderr, "hessian_inverse_from_score: failed\n");
270 	    gretl_matrix_free(H);
271 	    H = NULL;
272 	}
273     }
274 
275     return H;
276 }
277 
278 struct uhess_data {
279     GENERATOR *genr;
280     DATASET *dset;
281 };
282 
283 /* Callback from numerical_hessian() for use in user_hess().
284    The first argument is redundant here, since the user
285    matrix referenced in the function-call in @genr will
286    already contain the values in @b. But we need to
287    respect the typedef for BFGS_CRIT_FUNC.
288 */
289 
uhess_callback(const double * b,void * data)290 static double uhess_callback (const double *b, void *data)
291 {
292     struct uhess_data *uh = data;
293     double ret = NADBL;
294     int err;
295 
296     err = execute_genr(uh->genr, uh->dset, NULL);
297     if (!err) {
298 	ret = get_scalar_value_by_name("$umax", &err);
299     }
300 
301     return ret;
302 }
303 
304 /* apparatus for constructing numerical approximation to
305    the Hessian */
306 
hess_h_init(double * h,double * h0,int n)307 static void hess_h_init (double *h, double *h0, int n)
308 {
309     memcpy(h, h0, n * sizeof *h);
310 }
311 
hess_h_reduce(double * h,double v,int n)312 static void hess_h_reduce (double *h, double v, int n)
313 {
314     int i;
315 
316     for (i=0; i<n; i++) {
317 	h[i] /= v;
318     }
319 }
320 
321 /* number of Richardson steps */
322 #define RSTEPS 4
323 
324 /* Default @d for numerical_hessian (2017-10-03: was 0.0001).
325    Note 2018-10-05: this "new" value seems to be much too big
326    in some cases.
327 */
328 #define numhess_d 0.01
329 
330 /* The algorithm below implements the method of Richardson
331    Extrapolation.  It is derived from code in the gnu R package
332    "numDeriv" by Paul Gilbert, which was in turn derived from code
333    by Xinqiao Liu.  Turned into C and modified for gretl by
334    Allin Cottrell, June 2006.  On successful completion, writes
335    the Hessian (or the negative Hessian, if @neg is non-zero)
336    into @H, which must be correctly sized to receive the result.
337 */
338 
numerical_hessian(double * b,gretl_matrix * H,BFGS_CRIT_FUNC func,void * data,int neg,double d)339 int numerical_hessian (double *b, gretl_matrix *H,
340 		       BFGS_CRIT_FUNC func, void *data,
341 		       int neg, double d)
342 {
343     double Dx[RSTEPS];
344     double Hx[RSTEPS];
345     double *wspace;
346     double *h0, *h, *Hd, *D;
347     int r = RSTEPS;
348     double dsmall = 0.0001;
349     double ztol, eps = 1e-4;
350     double v = 2.0;    /* reduction factor for h */
351     double f0, f1, f2;
352     double p4m, hij;
353     double bi0, bj0;
354     int n = gretl_matrix_rows(H);
355     int vn = (n * (n + 1)) / 2;
356     int dn = vn + n;
357     int i, j, k, m, u;
358     int err = 0;
359 
360     if (d == 0.0) {
361 	d = numhess_d;
362     }
363 
364     wspace = malloc((3 * n + dn) * sizeof *wspace);
365     if (wspace == NULL) {
366 	return E_ALLOC;
367     }
368 
369     h0 = wspace;
370     h = h0 + n;
371     Hd = h + n;
372     D = Hd + n; /* D is of length dn */
373 
374 #if 0
375     ztol = sqrt(DBL_EPSILON / 7e-7); /* as per R */
376 #else
377     ztol = 0.01;
378 #endif
379 
380  try_again:
381 
382     /* note: numDeriv has
383 
384        h0 <- abs(d*x) + eps * (abs(x) < zero.tol)
385 
386        where the defaults are eps = 1e-4, d = 0.1,
387        and zero.tol = sqrt(double.eps/7e-7)
388 
389        C translation:
390        double ztol = sqrt(DBL_EPSILON / 7e-7);
391        h0[i] = fabs(d*b[i]) + eps * (fabs(b[i]) < ztol);
392 
393        The above @ztol is about 1.78e-05. Below, we are
394        currently using a bigger value, 0.01.
395     */
396     for (i=0; i<n; i++) {
397 	h0[i] = fabs(d*b[i]) + eps * (fabs(b[i]) < ztol);
398     }
399 
400     f0 = func(b, data);
401 
402     /* first derivatives and Hessian diagonal */
403 
404     for (i=0; i<n; i++) {
405 	bi0 = b[i];
406 	hess_h_init(h, h0, n);
407 	for (k=0; k<r; k++) {
408 	    b[i] = bi0 + h[i];
409 	    f1 = func(b, data);
410 	    if (na(f1)) {
411 		if (d <= dsmall) {
412 		    fprintf(stderr, "numerical_hessian: 1st derivative: "
413 			    "criterion=NA for theta[%d] = %g (d=%g)\n", i, b[i], d);
414 		}
415 		b[i] = bi0;
416 		err = E_NAN;
417 		goto end_first_try;
418 	    }
419 	    b[i] = bi0 - h[i];
420 	    f2 = func(b, data);
421 	    if (na(f2)) {
422 		if (d <= dsmall) {
423 		    fprintf(stderr, "numerical_hessian: 1st derivative: "
424 			    "criterion=NA for theta[%d] = %g (d=%g)\n", i, b[i], d);
425 		}
426 		b[i] = bi0;
427 		err = E_NAN;
428 		goto end_first_try;
429 	    }
430 	    /* F'(i) */
431 	    Dx[k] = (f1 - f2) / (2 * h[i]);
432 	    /* F''(i) */
433 	    Hx[k] = (f1 - 2*f0 + f2) / (h[i] * h[i]);
434 	    hess_h_reduce(h, v, n);
435 	}
436 	b[i] = bi0;
437 	p4m = 4.0;
438 	for (m=0; m<r-1; m++) {
439 	    for (k=0; k<r-m-1; k++) {
440 		Dx[k] = (Dx[k+1] * p4m - Dx[k]) / (p4m - 1);
441 		Hx[k] = (Hx[k+1] * p4m - Hx[k]) / (p4m - 1);
442 	    }
443 	    p4m *= 4.0;
444 	}
445 	D[i] = Dx[0];
446 	Hd[i] = Hx[0];
447     }
448 
449     /* second derivatives: lower half of Hessian only */
450 
451     u = n;
452     for (i=0; i<n; i++) {
453 	bi0 = b[i];
454 	for (j=0; j<=i; j++) {
455 	    if (i == j) {
456 		D[u] = Hd[i];
457 	    } else {
458 		hess_h_init(h, h0, n);
459 		bj0 = b[j];
460 		for (k=0; k<r; k++) {
461 		    b[i] = bi0 + h[i];
462 		    b[j] = bj0 + h[j];
463 		    f1 = func(b, data);
464 		    if (na(f1)) {
465 			if (d <= dsmall) {
466 			    fprintf(stderr, "numerical_hessian: 2nd derivatives (%d,%d): "
467 				    "objective function gave NA\n", i, j);
468 			}
469 			b[i] = bi0;
470 			b[j] = bj0;
471 			err = E_NAN;
472 			goto end_first_try;
473 		    }
474 		    b[i] = bi0 - h[i];
475 		    b[j] = bj0 - h[j];
476 		    f2 = func(b, data);
477 		    if (na(f2)) {
478 			if (d <= dsmall) {
479 			    fprintf(stderr, "numerical_hessian: 2nd derivatives (%d,%d): "
480 				    "objective function gave NA\n", i, j);
481 			}
482 			b[i] = bi0;
483 			b[j] = bj0;
484 			err = E_NAN;
485 			goto end_first_try;
486 		    }
487 		    /* cross-partial */
488 		    Dx[k] = (f1 - 2*f0 + f2 - Hd[i]*h[i]*h[i]
489 			     - Hd[j]*h[j]*h[j]) / (2*h[i]*h[j]);
490 		    hess_h_reduce(h, v, n);
491 		}
492 		p4m = 4.0;
493 		for (m=0; m<r-1; m++) {
494 		    for (k=0; k<r-m-1; k++) {
495 			Dx[k] = (Dx[k+1] * p4m - Dx[k]) / (p4m - 1);
496 		    }
497 		    p4m *= 4.0;
498 		}
499 		D[u] = Dx[0];
500 		b[j] = bj0;
501 	    }
502 	    u++;
503 	}
504 	b[i] = bi0;
505     }
506 
507  end_first_try:
508     if (err == E_NAN && d > dsmall) {
509 	err = 0;
510 	gretl_error_clear();
511 	d /= 10;
512 	goto try_again;
513     }
514 
515     if (!err) {
516 	/* transcribe the (negative of?) the Hessian */
517 	u = n;
518 	for (i=0; i<n; i++) {
519 	    for (j=0; j<=i; j++) {
520 		hij = neg ? -D[u] : D[u];
521 		gretl_matrix_set(H, i, j, hij);
522 		gretl_matrix_set(H, j, i, hij);
523 		u++;
524 	    }
525 	}
526     }
527 
528     if (neg) {
529 	/* internal use, not user_numhess(): we should ensure
530 	   that the original criterion value is restored after
531 	   calculating with a perturbed version of @b
532 	*/
533 	func(b, data);
534     }
535 
536     if (err && err != E_ALLOC) {
537 	gretl_errmsg_set(_("Failed to compute numerical Hessian"));
538     }
539 
540     free(wspace);
541 
542     return err;
543 }
544 
545 /**
546  * numerical_hessian_inverse:
547  * @b: array of parameter estimates.
548  * @n: the number of elements in @b.
549  * @func: function to compute criterion.
550  * @data: data to be passed to the @gradfunc callback.
551  * @d: step size (give 0.0 for automatic).
552  * @err: location to receive error code.
553  *
554  * A wrapper for numerical_hessian() which takes care of
555  * (a) allocation of the Hessian and (b) inversion.
556  *
557  * Returns: the inverse of the (negative) Hessian on successful
558  * completion, NULL on error.
559  */
560 
numerical_hessian_inverse(const double * b,int n,BFGS_CRIT_FUNC func,void * data,double d,int * err)561 gretl_matrix *numerical_hessian_inverse (const double *b, int n,
562 					 BFGS_CRIT_FUNC func,
563 					 void *data, double d,
564 					 int *err)
565 {
566     gretl_matrix *H = gretl_zero_matrix_new(n, n);
567 
568     if (H == NULL) {
569 	*err = E_ALLOC;
570     } else {
571 	*err = numerical_hessian((double *) b, H, func, data, 1, d);
572     }
573 
574     if (!*err) {
575 	*err = gretl_invert_symmetric_matrix(H);
576 	if (*err) {
577 	    fprintf(stderr, "numerical_hessian_inverse: failed\n");
578 	    gretl_errmsg_set(_("Failed to compute numerical Hessian"));
579 	    gretl_matrix_free(H);
580 	    H = NULL;
581 	}
582     }
583 
584     return H;
585 }
586 
NR_fallback_hessian(double * b,gretl_matrix * H,BFGS_GRAD_FUNC gradfunc,BFGS_CRIT_FUNC cfunc,void * data)587 static int NR_fallback_hessian (double *b, gretl_matrix *H,
588 				BFGS_GRAD_FUNC gradfunc,
589 				BFGS_CRIT_FUNC cfunc,
590 				void *data)
591 {
592     if (gradfunc != NULL) {
593 	return hessian_from_score(b, H, gradfunc, cfunc, data);
594     } else {
595 	return numerical_hessian(b, H, cfunc, data, 1, 0.0);
596     }
597 }
598 
599 #define ALT_OPG 0
600 
601 /* build the T x k matrix G, given a set of coefficient estimates,
602    @b, and a function for calculating the per-observation contributions
603    to the loglikelihood, @lltfun
604 */
605 
numerical_score_matrix(double * b,int T,int k,BFGS_LLT_FUNC lltfun,void * data,int * err)606 gretl_matrix *numerical_score_matrix (double *b, int T, int k,
607 				      BFGS_LLT_FUNC lltfun,
608 				      void *data, int *err)
609 {
610     double h = 1e-8;
611 #if ALT_OPG
612     double d = 1.0e-4;
613 #endif
614     gretl_matrix *G;
615     const double *x;
616     double bi0, x0;
617     int i, t;
618 
619     G = gretl_zero_matrix_new(T, k);
620     if (G == NULL) {
621 	*err = E_ALLOC;
622 	return NULL;
623     }
624 
625     for (i=0; i<k; i++) {
626 	bi0 = b[i];
627 #if ALT_OPG
628 	h = d * bi0 + d * (floateq(b[i], 0.0));
629 #endif
630 	b[i] = bi0 - h;
631 	x = lltfun(b, i, data);
632 	if (x == NULL) {
633 	    *err = E_NAN;
634 	    goto bailout;
635 	}
636 	for (t=0; t<T; t++) {
637 	    gretl_matrix_set(G, t, i, x[t]);
638 	}
639 	b[i] = bi0 + h;
640 	x = lltfun(b, i, data);
641 	if (x == NULL) {
642 	    *err = E_NAN;
643 	    goto bailout;
644 	}
645 	for (t=0; t<T; t++) {
646 	    x0 = gretl_matrix_get(G, t, i);
647 	    gretl_matrix_set(G, t, i, (x[t] - x0) / (2.0 * h));
648 	}
649 	b[i] = bi0;
650 #if NLS_DEBUG
651 	fprintf(stderr, "b[%d]: using %#.12g and %#.12g\n", i, bi0 - h, bi0 + h);
652 #endif
653     }
654 
655 #if NLS_DEBUG
656     gretl_matrix_print(G, "Numerically estimated score");
657 #endif
658 
659  bailout:
660 
661     if (*err) {
662 	gretl_matrix_free(G);
663 	G = NULL;
664     }
665 
666     return G;
667 }
668 
richardson_gradient(double * b,double * g,int n,BFGS_CRIT_FUNC func,void * data)669 static int richardson_gradient (double *b, double *g, int n,
670 				BFGS_CRIT_FUNC func, void *data)
671 {
672     double df[RSTEPS];
673     double eps = 1.0e-4;
674     double d = 0.0001;
675     double h, p4m;
676     double bi0, f1, f2;
677     int r = RSTEPS;
678     int i, k, m;
679 
680     for (i=0; i<n; i++) {
681 	bi0 = b[i];
682 	h = fabs(d * b[i]) + eps * (floateq(b[i], 0.0));
683 	for (k=0; k<r; k++) {
684 	    b[i] = bi0 - h;
685 	    f1 = func(b, data);
686 	    b[i] = bi0 + h;
687 	    f2 = func(b, data);
688 	    if (na(f1) || na(f2)) {
689 		b[i] = bi0;
690 		return 1;
691 	    }
692 	    df[k] = (f2 - f1) / (2 * h);
693 	    h /= 2.0;
694 	}
695 	b[i] = bi0;
696 	p4m = 4.0;
697 	for (m=0; m<r-1; m++) {
698 	    for (k=0; k<r-m-1; k++) {
699 		df[k] = (df[k+1] * p4m - df[k]) / (p4m - 1.0);
700 	    }
701 	    p4m *= 4.0;
702 	}
703 	g[i] = df[0];
704     }
705 
706     return 0;
707 }
708 
709 /* trigger for switch to Richardson gradient */
710 #define B_RELMIN 1.0e-14
711 
simple_gradient(double * b,double * g,int n,BFGS_CRIT_FUNC func,void * data,int * redo)712 static int simple_gradient (double *b, double *g, int n,
713 			    BFGS_CRIT_FUNC func, void *data,
714 			    int *redo)
715 {
716     const double h = 1.0e-8;
717     double bi0, f1, f2;
718     int i;
719 
720     for (i=0; i<n; i++) {
721 	bi0 = b[i];
722 	b[i] = bi0 - h;
723 	if (bi0 != 0.0 && fabs((bi0 - b[i]) / bi0) < B_RELMIN) {
724 	    fprintf(stderr, "numerical gradient: switching to Richardson\n");
725 	    *redo = 1;
726 	    return 0;
727 	}
728 	f1 = func(b, data);
729 	b[i] = bi0 + h;
730 	f2 = func(b, data);
731 	b[i] = bi0;
732 	if (na(f1) || na(f2)) {
733 	    return 1;
734 	}
735 	g[i] = (f2 - f1) / (2.0 * h);
736 #if BFGS_DEBUG > 1
737 	fprintf(stderr, "g[%d] = (%.16g - %.16g) / (2.0 * %g) = %g\n",
738 		i, f2, f1, h, g[i]);
739 #endif
740     }
741 
742     return 0;
743 }
744 
745 /* default numerical calculation of gradient in context of BFGS */
746 
numeric_gradient(double * b,double * g,int n,BFGS_CRIT_FUNC func,void * data)747 int numeric_gradient (double *b, double *g, int n,
748 		      BFGS_CRIT_FUNC func, void *data)
749 {
750     int err = 0;
751 
752     if (libset_get_bool(BFGS_RSTEP)) {
753 	err = richardson_gradient(b, g, n, func, data);
754     } else {
755 	int redo = 0;
756 
757 	err = simple_gradient(b, g, n, func, data, &redo);
758 	if (redo) {
759 	    err = richardson_gradient(b, g, n, func, data);
760 	}
761     }
762 
763 #if BFGS_DEBUG
764     fprintf(stderr, "numeric_gradient returning, err = %d\n", err);
765 #endif
766 
767     return err;
768 }
769 
770 #define STEPFRAC	0.2
771 #define acctol		1.0e-7 /* alt: 0.0001 or 1.0e-7 (?) */
772 #define reltest		10.0
773 
774 #define coeff_unchanged(a,b) (reltest + a == reltest + b)
775 
broken_gradient(double * g,int n)776 static int broken_gradient (double *g, int n)
777 {
778     int i;
779 
780     for (i=0; i<n; i++) {
781 	if (isnan(g[i])) {
782 	    return 1;
783 	}
784     }
785 
786     return 0;
787 }
788 
789 /*
790    If "set initvals" has been used, replace whatever initial values
791    might have been in place with those given by the user (the customer
792    is always right).  In addition, respect user settings for the
793    maximum number of iterations, the convergence tolerance and
794    so on.
795 */
796 
optim_get_user_values(double * b,int n,int * maxit,double * reltol,double * gradmax,gretlopt opt,PRN * prn)797 static void optim_get_user_values (double *b, int n, int *maxit,
798 				   double *reltol, double *gradmax,
799 				   gretlopt opt, PRN *prn)
800 {
801     int umaxit;
802     double utol;
803 
804     if (opt & OPT_U) {
805 	/* we first check to see if we've been a usable initialization
806 	   for the parameter estimates */
807 	gretl_matrix *uinit;
808 	int i, uilen;
809 
810 	uinit = get_initvals();
811 	uilen = gretl_vector_get_length(uinit);
812 
813 	if (uilen > 0) {
814 	    /* the user has given something */
815 	    if (uilen < n) {
816 		fprintf(stderr, "Only %d initial values given, but %d "
817 			"are necessary\n", uilen, n);
818 	    } else {
819 		for (i=0; i<n; i++) {
820 		    b[i] = uinit->val[i];
821 		}
822 		if ((opt & OPT_V) && !(opt & OPT_A)) {
823 		    /* OPT_A: arma: this is handled elsewhere */
824 		    pputs(prn, _("\n\n*** User-specified starting values:\n"));
825 		    for (i=0; i<n; i++) {
826 			pprintf(prn, " %12.6f", b[i]);
827 			if (i % 6 == 5) {
828 			    pputc(prn, '\n');
829 			}
830 		    }
831 		    pputs(prn, "\n\n");
832 		}
833 	    }
834 	}
835 	gretl_matrix_free(uinit);
836     }
837 
838     if (reltol == NULL || gradmax == NULL) {
839 	/* Newton */
840 	return;
841     }
842 
843     /* check for a setting of the maximum number of iterations */
844     umaxit = libset_get_int(BFGS_MAXITER);
845     if (umaxit >= 0) {
846 	*maxit = umaxit;
847     } else if (*maxit < 0) {
848 	*maxit = BFGS_MAXITER_DEFAULT;
849     }
850 
851     /* convergence tolerance */
852     utol = libset_get_user_tolerance(BFGS_TOLER);
853     if (!na(utol)) {
854 	/* the user has actually set a value */
855 	*reltol = utol;
856 	if (!(opt & OPT_Q)) {
857 	    fprintf(stderr, "user-specified BFGS tolerance = %g\n", utol);
858 	}
859     } else if (*reltol == 0) {
860 	/* use the generic BFGS default */
861 	*reltol = libset_get_double(BFGS_TOLER);
862     }
863 
864     /* maximum acceptable gradient norm */
865     *gradmax = libset_get_double(BFGS_MAXGRAD);
866 }
867 
868 #define bfgs_print_iter(v,s,i) (v && (s == 1 || i % s == 0))
869 
870 #define GRAD_TOLER 1.0
871 
copy_initial_hessian(double ** H,const gretl_matrix * A,int n)872 static int copy_initial_hessian (double **H,
873 				 const gretl_matrix *A,
874 				 int n)
875 {
876     int i, j, vlen = gretl_vector_get_length(A);
877     int err = 0;
878 
879 #if BFGS_DEBUG > 1
880     gretl_matrix_print(A, "BFGS: initial Hessian inverse");
881 #endif
882 
883     if (gretl_is_null_matrix(A)) {
884 	/* set identity matrix */
885 	for (i=0; i<n; i++) {
886 	    for (j=0; j<i; j++) {
887 		H[i][j] = 0.0;
888 	    }
889 	    H[i][i] = 1.0;
890 	}
891     } else if (vlen == n) {
892 	/* set the diagonal */
893 	for (i=0; i<n; i++) {
894 	    for (j=0; j<i; j++) {
895 		H[i][j] = 0.0;
896 	    }
897 	    H[i][i] = A->val[i];
898 	}
899     } else  if (A->rows == n && A->cols == n) {
900 	/* set the whole matrix */
901 	for (i=0; i<n; i++) {
902 	    for (j=0; j<=i; j++) {
903 		H[i][j] = gretl_matrix_get(A, i, j);
904 	    }
905 	}
906     } else {
907 	err = E_NONCONF;
908     }
909 
910     return err;
911 }
912 
optim_fncall(BFGS_CRIT_FUNC cfunc,double * b,void * data,int minimize)913 static double optim_fncall (BFGS_CRIT_FUNC cfunc,
914 			    double *b, void *data,
915 			    int minimize)
916 {
917     double ret = cfunc(b, data);
918 
919     return na(ret) ? ret : minimize ? -ret : ret;
920 }
921 
optim_gradcall(BFGS_GRAD_FUNC gradfunc,double * b,double * g,int n,BFGS_CRIT_FUNC cfunc,void * data,int minimize)922 static int optim_gradcall (BFGS_GRAD_FUNC gradfunc,
923 			   double *b, double *g, int n,
924 			   BFGS_CRIT_FUNC cfunc,
925 			   void *data,
926 			   int minimize)
927 {
928     int ret = gradfunc(b, g, n, cfunc, data);
929 
930     if (minimize) {
931 	int i;
932 
933 	for (i=0; i<n; i++) {
934 	    if (!na(g[i])) {
935 		g[i] = -g[i];
936 	    }
937 	}
938     }
939 
940     return ret;
941 }
942 
simple_slen(int n,int * pndelta,double * b,double * X,double * t,double * pf,BFGS_CRIT_FUNC cfunc,void * data,double g0,double f0,int * pfcount,int minimize)943 static double simple_slen (int n, int *pndelta, double *b, double *X, double *t,
944 			   double *pf, BFGS_CRIT_FUNC cfunc, void *data,
945 			   double g0, double f0, int *pfcount, int minimize)
946 {
947     double d, steplen = 1.0;
948     double f1 = *pf;
949     int i, crit_ok = 0, fcount = 0;
950     int ndelta = *pndelta;
951 
952     /* Below: iterate so long as (a) we haven't achieved an acceptable
953        value of the criterion and (b) there is still some prospect
954        of doing so.
955     */
956 
957     do {
958 	ndelta = n;
959 	crit_ok = 0;
960 	for (i=0; i<n; i++) {
961 	    b[i] = X[i] + steplen * t[i];
962 	    if (coeff_unchanged(b[i], X[i])) {
963 		ndelta--;
964 	    }
965 	}
966 	if (ndelta > 0) {
967 	    f1 = optim_fncall(cfunc, b, data, minimize);
968 	    fcount++;
969 	    d = g0 * steplen * acctol;
970 	    crit_ok = !na(f1) && (f1 >= f0 + d);
971 	    if (!crit_ok) {
972 		/* calculated criterion no good: try smaller step */
973 		steplen *= STEPFRAC;
974 	    }
975 	}
976     } while (ndelta != 0 && !crit_ok);
977 
978     *pndelta = ndelta;
979     *pfcount += fcount;
980     *pf = f1;
981 
982     return steplen;
983 }
984 
BFGS_orig(double * b,int n,int maxit,double reltol,int * fncount,int * grcount,BFGS_CRIT_FUNC cfunc,int crittype,BFGS_GRAD_FUNC gradfunc,void * data,const gretl_matrix * A0,gretlopt opt,PRN * prn)985 static int BFGS_orig (double *b, int n, int maxit, double reltol,
986 		      int *fncount, int *grcount, BFGS_CRIT_FUNC cfunc,
987 		      int crittype, BFGS_GRAD_FUNC gradfunc, void *data,
988 		      const gretl_matrix *A0, gretlopt opt, PRN *prn)
989 {
990     int verbskip, verbose = (opt & OPT_V);
991     int minimize = (opt & OPT_I);
992     double *wspace = NULL;
993     double **H = NULL;
994     double *g, *t, *X, *c;
995     int fcount, gcount, ndelta = 0;
996     int show_activity = 0;
997     double sumgrad, gradmax, gradnorm = 0.0;
998     double fmax, f, f0, s, steplen = 0.0;
999     double fdiff, D1, D2;
1000     int i, j, ilast, iter, done = 0;
1001     int err = 0;
1002 
1003     optim_get_user_values(b, n, &maxit, &reltol, &gradmax, opt, prn);
1004 
1005     wspace = malloc(4 * n * sizeof *wspace);
1006     H = triangular_array_new(n);
1007     if (wspace == NULL || H == NULL) {
1008 	err = E_ALLOC;
1009 	goto bailout;
1010     }
1011 
1012     if (gradfunc == NULL) {
1013 	gradfunc = numeric_gradient;
1014     }
1015 
1016     /* initialize curvature matrix */
1017     if (A0 != NULL) {
1018 	err = copy_initial_hessian(H, A0, n);
1019     } else {
1020 	gretl_matrix *A1 = get_initcurv();
1021 
1022 	err = copy_initial_hessian(H, A1, n);
1023 	gretl_matrix_free(A1);
1024     }
1025     if (err) {
1026 	goto bailout;
1027     }
1028 
1029     g = wspace;
1030     t = g + n;
1031     X = t + n;
1032     c = X + n;
1033 
1034     f = optim_fncall(cfunc, b, data, minimize);
1035 
1036     if (na(f)) {
1037 	gretl_errmsg_set(_("BFGS: initial value of objective function is not finite"));
1038 	err = E_NAN;
1039 	goto bailout;
1040     }
1041 
1042 #if BFGS_DEBUG
1043     fprintf(stderr, "*** BFGS: first evaluation of f = %g\n", f);
1044 #endif
1045 
1046     f0 = fmax = f;
1047     iter = ilast = fcount = gcount = 1;
1048     optim_gradcall(gradfunc, b, g, n, cfunc, data, minimize);
1049 
1050 #if BFGS_DEBUG > 1
1051     fprintf(stderr, "initial gradient:\n");
1052     for (i=0; i<n; i++) {
1053 	fprintf(stderr, " g[%d] = %g\n", i, g[i]);
1054     }
1055 #endif
1056 
1057     if (maxit == 0) {
1058 	goto skipcalc;
1059     }
1060 
1061     verbskip = libset_get_int(BFGS_VERBSKIP);
1062     show_activity = show_activity_func_installed();
1063 
1064     do {
1065 	if (bfgs_print_iter(verbose, verbskip, iter)) {
1066 	    print_iter_info(iter, f, crittype, n, b, g, steplen, prn);
1067 	}
1068 
1069 	if (show_activity && (iter % 10 == 0)) {
1070 	    show_activity_callback();
1071 	}
1072 
1073 	if (iter > 1 && ilast == gcount) {
1074 	    /* restart: set curvature matrix to I */
1075 	    for (i=0; i<n; i++) {
1076 		for (j=0; j<i; j++) {
1077 		    H[i][j] = 0.0;
1078 		}
1079 		H[i][i] = 1.0;
1080 	    }
1081 	}
1082 
1083 	for (i=0; i<n; i++) {
1084 	    /* copy coefficients to X, gradient to c */
1085 	    X[i] = b[i];
1086 	    c[i] = g[i];
1087 	}
1088 
1089 	gradnorm = sumgrad = 0.0;
1090 
1091 	for (i=0; i<n; i++) {
1092 	    s = 0.0;
1093 	    for (j=0; j<=i; j++) {
1094 		s += H[i][j] * g[j];
1095 	    }
1096 	    for (j=i+1; j<n; j++) {
1097 		s += H[j][i] * g[j];
1098 	    }
1099 	    t[i] = s;
1100 	    sumgrad += s * g[i];
1101 	    gradnorm += fabs(b[i] * g[i]);
1102 	}
1103 
1104 	gradnorm = sqrt(gradnorm / n);
1105 
1106 #if BFGS_DEBUG
1107 	fprintf(stderr, "\niter %d: sumgrad=%g, gradnorm=%g\n",
1108 		iter, sumgrad, gradnorm);
1109 #endif
1110 
1111 #if BFGS_DEBUG > 1
1112 	fprintf(stderr, "H = \n");
1113 	for (i=0; i<n; i++) {
1114 	    for (j=0; j<=i; j++) {
1115 		fprintf(stderr, "%15.6f", H[i][j]);
1116 	    }
1117 	    fputc('\n', stderr);
1118 	}
1119 #endif
1120 	if (sumgrad > 0.0) {
1121 	    /* heading in the right direction (uphill) */
1122 	    steplen = simple_slen(n, &ndelta, b, X, t, &f, cfunc, data,
1123 				  sumgrad, fmax, &fcount, minimize);
1124 	    fdiff = fabs(fmax - f);
1125 	    if (iter > 1 || fdiff > 0) {
1126 		done = fdiff <= reltol * (fabs(fmax) + reltol);
1127 #if BFGS_DEBUG
1128 		fprintf(stderr, "convergence test: LHS=%g, RHS=%g; done=%d\n",
1129 			fdiff, reltol * (fabs(fmax) + reltol), done);
1130 #endif
1131 	    }
1132 
1133 	    /* prepare to stop if relative change is small enough */
1134 	    if (done) {
1135 		ndelta = 0;
1136 		fmax = f;
1137 	    }
1138 
1139 	    if (ndelta > 0) {
1140 		/* making progress */
1141 #if BFGS_DEBUG
1142 		fprintf(stderr, "making progress, ndelta = %d\n", ndelta);
1143 #endif
1144 		fmax = f;
1145 		optim_gradcall(gradfunc, b, g, n, cfunc, data, minimize);
1146 #if BFGS_DEBUG > 1
1147 		fprintf(stderr, "new gradient:\n");
1148 		for (i=0; i<n; i++) {
1149 		    fprintf(stderr, "%15.6f", g[i]);
1150 		}
1151 		fputc('\n', stderr);
1152 #endif
1153 		gcount++;
1154 		iter++;
1155 		D1 = 0.0;
1156 		for (i=0; i<n; i++) {
1157 		    t[i] *= steplen;
1158 		    c[i] -= g[i];
1159 		    D1 += t[i] * c[i];
1160 		}
1161 #if BFGS_DEBUG
1162 		fprintf(stderr, "D1 = %g\n", D1);
1163 #endif
1164 		if (D1 > 0.0) {
1165 		    D2 = 0.0;
1166 		    for (i=0; i<n; i++) {
1167 			s = 0.0;
1168 			for (j=0; j<=i; j++) {
1169 			    s += H[i][j] * c[j];
1170 			}
1171 			for (j=i+1; j<n; j++) {
1172 			    s += H[j][i] * c[j];
1173 			}
1174 			X[i] = s;
1175 			D2 += s * c[i];
1176 		    }
1177 		    D2 = 1.0 + D2 / D1;
1178 		    for (i=0; i<n; i++) {
1179 			for (j=0; j<=i; j++) {
1180 			    H[i][j] += (D2 * t[i]*t[j] - X[i]*t[j] - t[i]*X[j]) / D1;
1181 			}
1182 		    }
1183 #if BFGS_DEBUG
1184 		    fprintf(stderr, "D2 = %g\n", D2);
1185 #endif
1186 		} else {
1187 		    /* D1 <= 0.0 */
1188 		    ilast = gcount;
1189 		}
1190 	    } else if (ilast < gcount) {
1191 		ndelta = n;
1192 		ilast = gcount;
1193 	    }
1194 	} else if (sumgrad == 0.0) {
1195 #if 0
1196 	    fprintf(stderr, "gradient is exactly zero!\n");
1197 #endif
1198 	    break;
1199 	} else {
1200 	    /* heading in the wrong direction */
1201 	    if (ilast == gcount) {
1202 		/* we just did a reset, so don't reset again; instead set
1203 		   ndelta = 0 so that we exit the main loop
1204 		*/
1205 		ndelta = 0;
1206 		if (gcount == 1) {
1207 		    err = (broken_gradient(g, n))? E_NAN : E_NOCONV;
1208 		}
1209 	    } else {
1210 		/* reset for another attempt */
1211 		ilast = gcount;
1212 		ndelta = n;
1213 	    }
1214 	}
1215 
1216 	if (iter >= maxit) {
1217 	    break;
1218 	}
1219 
1220 	if (gcount - ilast > 2 * n) {
1221 	    /* periodic restart of curvature computation */
1222 	    ilast = gcount;
1223 	}
1224 
1225     } while (ndelta > 0 || ilast < gcount);
1226 
1227 #if BFGS_DEBUG
1228     fprintf(stderr, "terminated: fmax=%g, ndelta=%d, ilast=%d, gcount=%d\n",
1229 	    fmax, ndelta, ilast, gcount);
1230     fprintf(stderr, "gradnorm = %g, vs gradmax = %g\n", gradnorm, gradmax);
1231 #endif
1232 
1233     if (iter >= maxit) {
1234 	gretl_errmsg_sprintf(_("Reached the maximum iterations (%d)"), maxit);
1235 	err = E_NOCONV;
1236     } else if (gradnorm > gradmax) {
1237 	gretl_errmsg_sprintf(_("Norm of gradient %g exceeds maximum of %g"),
1238 			     gradnorm, gradmax);
1239 	err = E_NOCONV;
1240     } else if (fmax < f0) {
1241 	/* allow a small sloppiness factor here? */
1242 	double rdiff;
1243 
1244 	rdiff = (f0 == 0.0)? -fmax : fabs((f0 - fmax) / f0);
1245 	if (rdiff > 1.0e-12) {
1246 	    fprintf(stderr, "failed to match initial value of objective function:\n"
1247 		    " f0=%.18g, fmax=%.18g\n", f0, fmax);
1248 	    err = E_NOCONV;
1249 	}
1250     }
1251 
1252     if (!err && gradnorm > GRAD_TOLER) {
1253 	gretl_warnmsg_sprintf(_("norm of gradient = %g"), gradnorm);
1254 	set_gretl_warning(W_GRADIENT);
1255     }
1256 
1257  skipcalc:
1258 
1259     /* particularly relevant for iterated GMM: increment,
1260        don't just set, these two counts
1261     */
1262     *fncount += fcount;
1263     *grcount += gcount;
1264 
1265     if (verbose) {
1266 	print_iter_info(-1, f, crittype, n, b, g, steplen, prn);
1267 	/* pputc(prn, '\n'); */
1268     }
1269 
1270  bailout:
1271 
1272     free(wspace);
1273     free_triangular_array(H, n);
1274 
1275 #if BFGS_DEBUG
1276     fprintf(stderr, "BFGS_max: returning %d\n", err);
1277 #endif
1278 
1279     return err;
1280 }
1281 
1282 /* Note: we need this because the original L-BFGS-B code is
1283    set up as a minimizer.  We could get rid of it if anyone
1284    has the strength to go into lbfgsb.c (ex Fortran) and make
1285    the necessary adjustments.
1286 */
1287 
reverse_gradient(double * g,int n)1288 static void reverse_gradient (double *g, int n)
1289 {
1290     int i;
1291 
1292     for (i=0; i<n; i++) {
1293 	if (!na(g[i])) {
1294 	    g[i] = -g[i];
1295 	}
1296     }
1297 }
1298 
transcribe_lbfgs_bounds(const gretl_matrix * m,int nparm,int * nbd,double * l,double * u)1299 static int transcribe_lbfgs_bounds (const gretl_matrix *m,
1300 				    int nparm, int *nbd,
1301 				    double *l, double *u)
1302 {
1303     double h = libset_get_double(CONV_HUGE);
1304     int i, j, c = gretl_matrix_cols(m);
1305     int err = 0;
1306 
1307     if (c != 3) {
1308 	fprintf(stderr, "lbfgs_bounds: matrix should have 3 cols\n");
1309 	return E_INVARG;
1310     }
1311 
1312     for (i=0; i<nparm; i++) {
1313 	/* mark as unbounded */
1314 	nbd[i] = 0;
1315     }
1316 
1317     for (i=0; i<m->rows && !err; i++) {
1318 	j = (int) gretl_matrix_get(m, i, 0);
1319 	if (j < 1 || j > nparm) {
1320 	    fprintf(stderr, "lbfgs_bounds: out-of-bounds index %d\n", j);
1321 	    err = E_INVARG;
1322 	} else {
1323 	    j--; /* convert to zero-based */
1324 	    l[j] = gretl_matrix_get(m, i, 1);
1325 	    u[j] = gretl_matrix_get(m, i, 2);
1326 	    if (l[j] > u[j]) {
1327 		err = E_INVARG;
1328 	    } else if (l[j] != -h && u[j] != h) {
1329 		/* both lower and upper bounds */
1330 		nbd[j] = 2;
1331 	    } else if (l[j] != -h) {
1332 		/* lower bound only */
1333 		nbd[j] = 1;
1334 	    } else if (u[j] != h) {
1335 		/* upper bound only */
1336 		nbd[j] = 3;
1337 	    }
1338 	}
1339     }
1340 
1341     return err;
1342 }
1343 
LBFGS_max(double * b,int n,int maxit,double reltol,int * fncount,int * grcount,BFGS_CRIT_FUNC cfunc,int crittype,BFGS_GRAD_FUNC gradfunc,BFGS_COMBO_FUNC combfunc,void * data,const gretl_matrix * bounds,gretlopt opt,PRN * prn)1344 int LBFGS_max (double *b, int n,
1345 	       int maxit, double reltol,
1346 	       int *fncount, int *grcount,
1347 	       BFGS_CRIT_FUNC cfunc, int crittype,
1348 	       BFGS_GRAD_FUNC gradfunc,
1349 	       BFGS_COMBO_FUNC combfunc,
1350 	       void *data,
1351 	       const gretl_matrix *bounds,
1352 	       gretlopt opt,
1353 	       PRN *prn)
1354 {
1355     double *wspace = NULL;
1356     int *ispace = NULL;
1357     double *g, *l, *u, *wa;
1358     int *iwa, *nbd;
1359     int i, m, dim;
1360     char task[60];
1361     char csave[60];
1362     double f, pgtol;
1363     double factr;
1364     double gradmax;
1365     double dsave[29];
1366     int isave[44];
1367     int lsave[4];
1368     int iter, ibak = 0;
1369     int show_activity = 0;
1370     int maximize;
1371     int verbskip, verbose = (opt & OPT_V);
1372     int err = 0;
1373 
1374     maximize = (crittype != C_SSR) && !(opt & OPT_I);
1375 
1376     *fncount = *grcount = 0;
1377 
1378     optim_get_user_values(b, n, &maxit, &reltol, &gradmax, opt, prn);
1379 
1380     /*
1381       m: the number of corrections used in the limited memory matrix.
1382       It is not altered by the routine.  Values of m < 3 are not
1383       recommended, and large values of m can result in excessive
1384       computing time. The range 3 <= m <= 20 is recommended.
1385 
1386       Was initially set to 5 (then 10, then 8; and 8 is the default).
1387     */
1388     m = libset_get_int(LBFGS_MEM);
1389 
1390     dim = (2*m+5)*n + 11*m*m + 8*m; /* for wa */
1391     dim += 3*n;                     /* for g, l and u */
1392 
1393     wspace = malloc(dim * sizeof *wspace);
1394     ispace = malloc(4*n * sizeof *ispace);
1395 
1396     if (wspace == NULL || ispace == NULL) {
1397 	err = E_ALLOC;
1398 	goto bailout;
1399     }
1400 
1401     g = wspace;
1402     l = g + n;
1403     u = l + n;
1404     wa = u + n;
1405 
1406     nbd = ispace;
1407     iwa = nbd + n;
1408 
1409     verbskip = libset_get_int(BFGS_VERBSKIP);
1410     show_activity = show_activity_func_installed();
1411 
1412     if (gradfunc == NULL && combfunc == NULL) {
1413 	gradfunc = numeric_gradient;
1414     }
1415 
1416     /* Gradient convergence criterion (currently unused --
1417        we use reltol instead) */
1418     pgtol = 0.0;
1419 
1420     /* tol = (factr * macheps) => factr = tol/macheps */
1421     factr = reltol / pow(2.0, -52);
1422 
1423     if (!gretl_is_null_matrix(bounds)) {
1424 	/* Handle specified bounds on the parameters */
1425 	err = transcribe_lbfgs_bounds(bounds, n, nbd, l, u);
1426 	if (err) {
1427 	    goto bailout;
1428 	}
1429     } else {
1430 	/* By default we just set all parameters to be
1431 	   less than some ridiculously large number */
1432 	for (i=0; i<n; i++) {
1433 	    nbd[i] = 3; /* case 3: upper bound only */
1434 	    u[i] = DBL_MAX / 100;
1435 	}
1436     }
1437 
1438     /* Start the iteration by initializing @task */
1439     strcpy(task, "START");
1440 
1441     while (1) {
1442 	/* Call the L-BFGS-B code */
1443 	setulb_(&n, &m, b, l, u, nbd, &f, g, &factr, &pgtol, wa, iwa,
1444 		task, csave, lsave, isave, dsave);
1445 
1446 	iter = isave[29] + 1;
1447 
1448 	if (!strncmp(task, "FG", 2)) {
1449 	    /* Compute function value, f */
1450 	    if (combfunc != NULL) {
1451 		f = combfunc(b, g, n, data);
1452 	    } else {
1453 		f = cfunc(b, data);
1454 	    }
1455 	    if (!na(f)) {
1456 		if (maximize) f = -f;
1457 	    } else if (*fncount == 0) {
1458 		fprintf(stderr, "initial value of f is not finite\n");
1459 		err = E_DATA;
1460 		break;
1461 	    }
1462 	    *fncount += 1;
1463 	    if (combfunc == NULL) {
1464 		/* Compute gradient, g */
1465 		gradfunc(b, g, n, cfunc, data);
1466 	    }
1467 	    if (maximize) {
1468 		reverse_gradient(g, n);
1469 	    }
1470 	    *grcount += 1;
1471 	} else if (!strncmp(task, "NEW_X", 5)) {
1472 	    /* The optimizer has produced a new set of parameter values */
1473 	    if (isave[33] >= maxit) {
1474 		strcpy(task, "STOP: TOTAL NO. of f AND g "
1475 		       "EVALUATIONS EXCEEDS LIMIT");
1476 		err = E_NOCONV;
1477 		break;
1478 	    }
1479 	} else {
1480 	    if (strncmp(task, "CONVER", 6)) {
1481 		fprintf(stderr, "%s\n", task);
1482 	    }
1483 	    break;
1484 	}
1485 
1486 	if (bfgs_print_iter(verbose, verbskip, iter)) {
1487 	    if (iter != ibak) {
1488 		double steplen = (iter == 1)? NADBL : dsave[13];
1489 
1490 		if (maximize) reverse_gradient(g, n);
1491 		print_iter_info(iter, -f, crittype, n, b, g, steplen, prn);
1492 		if (maximize) reverse_gradient(g, n);
1493 	    }
1494 	    ibak = iter;
1495 	}
1496 
1497 	if (show_activity && (iter % 10 == 0)) {
1498 	    show_activity_callback();
1499 	}
1500     }
1501 
1502     if (!err && crittype == C_GMM) {
1503 	/* finalize GMM computations */
1504 	f = cfunc(b, data);
1505     }
1506 
1507     if (opt & OPT_V) {
1508 	if (maximize) reverse_gradient(g, n);
1509 	print_iter_info(-1, -f, crittype, n, b, g, dsave[13], prn);
1510 	pputc(prn, '\n');
1511     }
1512 
1513  bailout:
1514 
1515     free(wspace);
1516     free(ispace);
1517 
1518     return err;
1519 }
1520 
1521 /**
1522  * BFGS_max:
1523  * @b: array of adjustable coefficients.
1524  * @n: number elements in array @b.
1525  * @maxit: the maximum number of iterations to allow.
1526  * @reltol: relative tolerance for terminating iteration.
1527  * @fncount: location to receive count of function evaluations.
1528  * @grcount: location to receive count of gradient evaluations.
1529  * @cfunc: pointer to function used to calculate maximand.
1530  * @crittype: code for type of the maximand/minimand: should
1531  * be %C_LOGLIK, %C_GMM or %C_OTHER.  Used only in printing
1532  * iteration info.
1533  * @gradfunc: pointer to function used to calculate the
1534  * gradient, or %NULL for default numerical calculation.
1535  * @data: pointer that will be passed as the last
1536  * parameter to the callback functions @cfunc and @gradfunc.
1537  * @A0: initial approximation to the inverse of the Hessian
1538  * (or %NULL to use identity matrix)
1539  * @opt: may contain %OPT_V for verbose operation, %OPT_L to
1540  * force use of L-BFGS-B.
1541  * @prn: printing struct (or %NULL).  Only used if @opt
1542  * includes %OPT_V.
1543  *
1544  * Obtains the set of values for @b which jointly maximize the
1545  * criterion value as calculated by @cfunc. By default uses the BFGS
1546  * variable-metric method (based on Pascal code in J. C. Nash,
1547  * "Compact Numerical Methods for Computers," 2nd edition, converted
1548  * by p2c then re-crafted by B. D. Ripley for gnu R; revised for
1549  * gretl by Allin Cottrell and Jack Lucchetti). Alternatively,
1550  * if OPT_L is given, uses the L-BFGS-B method (limited memory
1551  * BFGS), based on Lbfgsb.3.0 by Ciyou Zhu, Richard Byrd, Jorge
1552  * Nocedal and Jose Luis Morales.
1553  *
1554  * Returns: 0 on successful completion, non-zero error code
1555  * on error.
1556  */
1557 
BFGS_max(double * b,int n,int maxit,double reltol,int * fncount,int * grcount,BFGS_CRIT_FUNC cfunc,int crittype,BFGS_GRAD_FUNC gradfunc,void * data,const gretl_matrix * A0,gretlopt opt,PRN * prn)1558 int BFGS_max (double *b, int n, int maxit, double reltol,
1559 	      int *fncount, int *grcount, BFGS_CRIT_FUNC cfunc,
1560 	      int crittype, BFGS_GRAD_FUNC gradfunc, void *data,
1561 	      const gretl_matrix *A0, gretlopt opt, PRN *prn)
1562 {
1563     int ret, wnum;
1564 
1565     gretl_iteration_push();
1566 
1567     if ((opt & OPT_L) || libset_get_bool(USE_LBFGS)) {
1568 	ret = LBFGS_max(b, n, maxit, reltol,
1569 			fncount, grcount, cfunc,
1570 			crittype, gradfunc, NULL, data,
1571 			NULL, opt, prn);
1572     } else {
1573 	ret = BFGS_orig(b, n, maxit, reltol,
1574 			fncount, grcount, cfunc,
1575 			crittype, gradfunc, data,
1576 			A0, opt, prn);
1577     }
1578 
1579     gretl_iteration_pop();
1580 
1581     wnum = check_gretl_warning();
1582     if (wnum != W_GRADIENT) {
1583 	/* suppress expected numerical warnings */
1584 	set_gretl_warning(0);
1585     }
1586 
1587     return ret;
1588 }
1589 
1590 /* constrained L_BFGS-B */
1591 
BFGS_cmax(double * b,int n,int maxit,double reltol,int * fncount,int * grcount,BFGS_CRIT_FUNC cfunc,int crittype,BFGS_GRAD_FUNC gradfunc,void * data,const gretl_matrix * bounds,gretlopt opt,PRN * prn)1592 static int BFGS_cmax (double *b, int n,
1593 		      int maxit, double reltol,
1594 		      int *fncount, int *grcount,
1595 		      BFGS_CRIT_FUNC cfunc, int crittype,
1596 		      BFGS_GRAD_FUNC gradfunc,
1597 		      void *data,
1598 		      const gretl_matrix *bounds,
1599 		      gretlopt opt, PRN *prn)
1600 {
1601     int ret, wnum;
1602 
1603     gretl_iteration_push();
1604 
1605     ret = LBFGS_max(b, n, maxit, reltol,
1606 		    fncount, grcount, cfunc,
1607 		    crittype, gradfunc, NULL, data,
1608 		    bounds, opt, prn);
1609 
1610     gretl_iteration_pop();
1611 
1612     wnum = check_gretl_warning();
1613     if (wnum != W_GRADIENT) {
1614 	/* suppress expected numerical warnings */
1615 	set_gretl_warning(0);
1616     }
1617 
1618     return ret;
1619 }
1620 
1621 /* user-level access to BFGS, NR and fdjac */
1622 
1623 typedef struct umax_ umax;
1624 
1625 struct umax_ {
1626     GretlType gentype;    /* GRETL_TYPE_DOUBLE or GRETL_TYPE_MATRIX */
1627     char *pxname;         /* name of scalar parameter value */
1628     gretl_matrix *b;      /* parameter vector */
1629     gretl_matrix *g;      /* gradient vector */
1630     gretl_matrix *h;      /* hessian matrix */
1631     int ncoeff;           /* number of coefficients */
1632     GENERATOR *gf;        /* for generating scalar or matrix result */
1633     GENERATOR *gg;        /* for generating gradient */
1634     GENERATOR *gh;        /* for generating Hessian */
1635     double fx_out;        /* function double value */
1636     gretl_matrix *fm_out; /* function matrix value */
1637     char gmname[VNAMELEN]; /* name of user-defined gradient vector */
1638     char hmname[VNAMELEN]; /* name of user-defined Hessian matrix */
1639     DATASET *dset;        /* dataset */
1640     PRN *prn;             /* optional printing struct */
1641 };
1642 
umax_new(GretlType t)1643 static umax *umax_new (GretlType t)
1644 {
1645     umax *u = malloc(sizeof *u);
1646 
1647     if (u != NULL) {
1648 	u->gentype = t;
1649 	u->pxname = NULL;
1650 	u->b = NULL;
1651 	u->g = NULL;
1652 	u->h = NULL;
1653 	u->ncoeff = 0;
1654 	u->gf = NULL;
1655 	u->gg = NULL;
1656 	u->gh = NULL;
1657 	u->fx_out = NADBL;
1658 	u->fm_out = NULL;
1659 	u->gmname[0] = '\0';
1660 	u->hmname[0] = '\0';
1661 	u->dset = NULL;
1662 	u->prn = NULL;
1663     }
1664 
1665     return u;
1666 }
1667 
umax_unset_no_replace_flag(umax * u)1668 static void umax_unset_no_replace_flag (umax *u)
1669 {
1670     user_var *uv = get_user_var_by_data(u->b);
1671 
1672     if (uv != NULL) {
1673 	user_var_unset_flag(uv, UV_NOREPL);
1674     }
1675 }
1676 
umax_destroy(umax * u)1677 static void umax_destroy (umax *u)
1678 {
1679     if (u->dset != NULL) {
1680 	/* drop any private "$" series created */
1681 	dataset_drop_listed_variables(NULL, u->dset, NULL, NULL);
1682     }
1683 
1684     umax_unset_no_replace_flag(u);
1685     user_var_delete_by_name("$umax", NULL);
1686     free(u->pxname);
1687 
1688     destroy_genr(u->gf);
1689     destroy_genr(u->gg);
1690     destroy_genr(u->gh);
1691 
1692     free(u);
1693 }
1694 
1695 /* user-defined optimizer: get the criterion value */
1696 
user_get_criterion(const double * b,void * p)1697 static double user_get_criterion (const double *b, void *p)
1698 {
1699     umax *u = (umax *) p;
1700     double x = NADBL;
1701     int i, t, err;
1702 
1703     for (i=0; i<u->ncoeff; i++) {
1704 	u->b->val[i] = b[i];
1705     }
1706 
1707     err = execute_genr(u->gf, u->dset, u->prn);
1708 
1709     if (err) {
1710 	return NADBL;
1711     }
1712 
1713     t = genr_get_output_type(u->gf);
1714 
1715     if (t == GRETL_TYPE_DOUBLE) {
1716 	x = genr_get_output_scalar(u->gf);
1717     } else if (t == GRETL_TYPE_MATRIX) {
1718 	gretl_matrix *m = genr_get_output_matrix(u->gf);
1719 
1720 	if (gretl_matrix_is_scalar(m)) {
1721 	    x = m->val[0];
1722 	} else {
1723 	    err = E_TYPES;
1724 	}
1725     } else {
1726 	err = E_TYPES;
1727     }
1728 
1729     u->fx_out = x;
1730 
1731     return x;
1732 }
1733 
user_get_criterion2(double b,void * p)1734 static double user_get_criterion2 (double b, void *p)
1735 {
1736     umax *u = (umax *) p;
1737     double x = NADBL;
1738     int t, err;
1739 
1740     gretl_scalar_set_value(u->pxname, b);
1741     err = execute_genr(u->gf, u->dset, u->prn);
1742 
1743     if (err) {
1744 	return NADBL;
1745     }
1746 
1747     t = genr_get_output_type(u->gf);
1748 
1749     if (t == GRETL_TYPE_DOUBLE) {
1750 	x = genr_get_output_scalar(u->gf);
1751     } else if (t == GRETL_TYPE_MATRIX) {
1752 	gretl_matrix *m = genr_get_output_matrix(u->gf);
1753 
1754 	if (gretl_matrix_is_scalar(m)) {
1755 	    x = m->val[0];
1756 	} else {
1757 	    err = E_TYPES;
1758 	}
1759     } else {
1760 	err = E_TYPES;
1761     }
1762 
1763     u->fx_out = x;
1764 
1765     return x;
1766 }
1767 
1768 /* user-defined optimizer: get the gradient, if specified */
1769 
user_get_gradient(double * b,double * g,int k,BFGS_CRIT_FUNC func,void * p)1770 static int user_get_gradient (double *b, double *g, int k,
1771 			      BFGS_CRIT_FUNC func, void *p)
1772 {
1773     umax *u = (umax *) p;
1774     gretl_matrix *ug;
1775     int i, err;
1776 
1777     for (i=0; i<k; i++) {
1778 	u->b->val[i] = b[i];
1779     }
1780 
1781     err = execute_genr(u->gg, u->dset, u->prn);
1782 
1783     if (err) {
1784 	return err;
1785     }
1786 
1787     ug = get_matrix_by_name(u->gmname);
1788 
1789     if (ug == NULL) {
1790 	err = E_UNKVAR;
1791     } else if (gretl_vector_get_length(ug) != k) {
1792 	err = E_NONCONF;
1793     } else {
1794 	for (i=0; i<k; i++) {
1795 	    g[i] = ug->val[i];
1796 	}
1797     }
1798 
1799     return err;
1800 }
1801 
1802 /* user-defined optimizer: get the hessian, if specified */
1803 
user_get_hessian(double * b,gretl_matrix * H,void * p)1804 static int user_get_hessian (double *b, gretl_matrix *H,
1805 			     void *p)
1806 {
1807     umax *u = (umax *) p;
1808     gretl_matrix *uH;
1809     int k = H->rows;
1810     int i, err;
1811 
1812     for (i=0; i<k; i++) {
1813 	u->b->val[i] = b[i];
1814     }
1815 
1816     err = execute_genr(u->gh, u->dset, u->prn);
1817 
1818     if (err) {
1819 	return err;
1820     }
1821 
1822     uH = get_matrix_by_name(u->hmname);
1823 
1824     if (uH == NULL) {
1825 	err = E_UNKVAR;
1826     } else if (uH->rows != k || uH->cols != k) {
1827 	err = E_NONCONF;
1828     } else {
1829 	gretl_matrix_copy_values(H, uH);
1830     }
1831 
1832     return err;
1833 }
1834 
1835 /* parse the name of the user gradient matrix (vector) or
1836    Hessian out of the associated function call, where it
1837    must be the first argument, given in pointer form
1838 */
1839 
optimizer_get_matrix_name(const char * fncall,char * name)1840 int optimizer_get_matrix_name (const char *fncall, char *name)
1841 {
1842     const char *s = strchr(fncall, '(');
1843     int n, err = 0;
1844 
1845     if (s == NULL) {
1846 	err = E_DATA;
1847     } else {
1848 	s++;
1849 	s += strspn(s, " ");
1850 	if (*s != '&') {
1851 	    err = E_TYPES;
1852 	} else {
1853 	    s++;
1854 	    n = gretl_namechar_spn(s);
1855 	    if (n >= VNAMELEN) {
1856 		err = E_DATA;
1857 	    } else {
1858 		strncat(name, s, n);
1859 	    }
1860 	}
1861     }
1862 
1863     return err;
1864 }
1865 
check_optimizer_scalar_parm(umax * u,const char * s)1866 static int check_optimizer_scalar_parm (umax *u, const char *s)
1867 {
1868     int n = gretl_namechar_spn(s);
1869     int err = 0;
1870 
1871     if (n > 0 && n < VNAMELEN) {
1872 	char vname[VNAMELEN];
1873 
1874 	*vname = '\0';
1875 	strncat(vname, s, n);
1876 	if (!gretl_is_scalar(vname)) {
1877 	    err = gretl_scalar_add(vname, NADBL);
1878 	}
1879 	if (!err) {
1880 	    u->pxname = gretl_strdup(vname);
1881 	}
1882     } else if (n >= VNAMELEN) {
1883 	err = E_INVARG;
1884     }
1885 
1886     return err;
1887 }
1888 
1889 /* Ensure that we can find the specified callback function,
1890    and that it cannot replace/move its param-vector argument,
1891    given by u->b.
1892 */
1893 
check_optimizer_callback(umax * u,const char * fncall)1894 static int check_optimizer_callback (umax *u, const char *fncall)
1895 {
1896     int n = strcspn(fncall, "(");
1897     int err = 0;
1898 
1899     if (n > 0 && n < FN_NAMELEN) {
1900 	char fname[FN_NAMELEN];
1901 	user_var *uvar = NULL;
1902 	ufunc *ufun;
1903 
1904 	*fname = '\0';
1905 	strncat(fname, fncall, n);
1906 	ufun = get_user_function_by_name(fname);
1907 	if (u->b == NULL) {
1908 	    check_optimizer_scalar_parm(u, fncall + n + 1);
1909 	} else {
1910 	    uvar = get_user_var_by_data(u->b);
1911 	}
1912 	if (ufun != NULL && uvar != NULL) {
1913 	    user_var_set_flag(uvar, UV_NOREPL);
1914 	}
1915     } else if (n >= FN_NAMELEN) {
1916 	err = E_INVARG;
1917     }
1918 
1919     return err;
1920 }
1921 
user_gen_setup(umax * u,const char * fncall,const char * gradcall,const char * hesscall,DATASET * dset)1922 static int user_gen_setup (umax *u,
1923 			   const char *fncall,
1924 			   const char *gradcall,
1925 			   const char *hesscall,
1926 			   DATASET *dset)
1927 {
1928     gchar *formula;
1929     int err;
1930 
1931     err = check_optimizer_callback(u, fncall);
1932     if (!err && gradcall != NULL) {
1933 	err = check_optimizer_callback(u, gradcall);
1934     }
1935     if (!err && hesscall != NULL) {
1936 	err = check_optimizer_callback(u, hesscall);
1937     }
1938     if (err) {
1939 	return err;
1940     }
1941 
1942     formula = g_strdup_printf("$umax=%s", fncall);
1943     u->gf = genr_compile(formula, dset, u->gentype, OPT_P,
1944 			 u->prn, &err);
1945 
1946     if (!err && gradcall != NULL) {
1947 	/* process gradient formula */
1948 	err = optimizer_get_matrix_name(gradcall, u->gmname);
1949 	if (!err) {
1950 	    u->gg = genr_compile(gradcall, dset, GRETL_TYPE_ANY,
1951 				 OPT_P | OPT_O, u->prn, &err);
1952 	}
1953     }
1954 
1955     if (!err && hesscall != NULL) {
1956 	/* process Hessian formula */
1957 	err = optimizer_get_matrix_name(hesscall, u->hmname);
1958 	if (!err) {
1959 	    u->gh = genr_compile(hesscall, dset, GRETL_TYPE_ANY,
1960 				 OPT_P | OPT_O, u->prn, &err);
1961 	}
1962     }
1963 
1964     if (!err) {
1965 	u->dset = dset;
1966 	u->fm_out = genr_get_output_matrix(u->gf);
1967     } else {
1968 	umax_unset_no_replace_flag(u);
1969 	destroy_genr(u->gf);
1970 	destroy_genr(u->gg);
1971 	u->gf = u->gg = NULL;
1972     }
1973 
1974     g_free(formula);
1975 
1976     return err;
1977 }
1978 
user_BFGS(gretl_matrix * b,const char * fncall,const char * gradcall,DATASET * dset,const gretl_matrix * bounds,int minimize,PRN * prn,int * err)1979 double user_BFGS (gretl_matrix *b,
1980 		  const char *fncall,
1981 		  const char *gradcall,
1982 		  DATASET *dset,
1983 		  const gretl_matrix *bounds,
1984 		  int minimize, PRN *prn,
1985 		  int *err)
1986 {
1987     umax *u;
1988     gretlopt opt = OPT_NONE;
1989     int maxit = BFGS_MAXITER_DEFAULT;
1990     int verbose, fcount = 0, gcount = 0;
1991     double tol;
1992     double ret = NADBL;
1993 
1994     u = umax_new(GRETL_TYPE_DOUBLE);
1995     if (u == NULL) {
1996 	*err = E_ALLOC;
1997 	return ret;
1998     }
1999 
2000     u->ncoeff = gretl_vector_get_length(b);
2001     if (u->ncoeff == 0) {
2002 	*err = E_DATA;
2003 	goto bailout;
2004     }
2005 
2006     u->b = b;
2007     u->prn = prn; /* placement of this? */
2008 
2009     *err = user_gen_setup(u, fncall, gradcall, NULL, dset);
2010     if (*err) {
2011 	return NADBL;
2012     }
2013 
2014     tol = libset_get_double(BFGS_TOLER);
2015     verbose = libset_get_int(MAX_VERBOSE);
2016 
2017     if (verbose) {
2018 	opt |= OPT_V;
2019     }
2020 
2021     if (minimize) {
2022 	opt |= OPT_I;
2023     }
2024 
2025     if (bounds != NULL) {
2026 	*err = BFGS_cmax(b->val, u->ncoeff,
2027 			 maxit, tol, &fcount, &gcount,
2028 			 user_get_criterion, C_OTHER,
2029 			 (u->gg == NULL)? NULL : user_get_gradient,
2030 			 u, bounds, opt, prn);
2031     } else {
2032 	*err = BFGS_max(b->val, u->ncoeff,
2033 			maxit, tol, &fcount, &gcount,
2034 			user_get_criterion, C_OTHER,
2035 			(u->gg == NULL)? NULL : user_get_gradient,
2036 			u, NULL, opt, prn);
2037     }
2038 
2039     if (fcount > 0 && (verbose || !gretl_looping())) {
2040 	pprintf(prn, _("Function evaluations: %d\n"), fcount);
2041 	pprintf(prn, _("Evaluations of gradient: %d\n"), gcount);
2042     }
2043 
2044     if (!*err) {
2045 	ret = u->fx_out;
2046     }
2047 
2048  bailout:
2049 
2050     umax_destroy(u);
2051 
2052     return ret;
2053 }
2054 
user_NR(gretl_matrix * b,const char * fncall,const char * gradcall,const char * hesscall,DATASET * dset,int minimize,PRN * prn,int * err)2055 double user_NR (gretl_matrix *b,
2056 		const char *fncall,
2057 		const char *gradcall,
2058 		const char *hesscall,
2059 		DATASET *dset,
2060 		int minimize,
2061 		PRN *prn, int *err)
2062 {
2063     umax *u;
2064     double crittol = 1.0e-7;
2065     double gradtol = 1.0e-7;
2066     gretlopt opt = OPT_NONE;
2067     int maxit = 100;
2068     int iters = 0;
2069     double ret = NADBL;
2070 
2071     u = umax_new(GRETL_TYPE_DOUBLE);
2072     if (u == NULL) {
2073 	*err = E_ALLOC;
2074 	return ret;
2075     }
2076 
2077     u->ncoeff = gretl_vector_get_length(b);
2078     if (u->ncoeff == 0) {
2079 	*err = E_DATA;
2080 	goto bailout;
2081     }
2082 
2083     u->b = b;
2084 
2085     *err = user_gen_setup(u, fncall, gradcall, hesscall, dset);
2086     if (*err) {
2087 	fprintf(stderr, "user_NR: failed on user_gen_setup\n");
2088 	return NADBL;
2089     }
2090 
2091     if (libset_get_int(MAX_VERBOSE)) {
2092 	opt |= OPT_V;
2093     }
2094 
2095     if (minimize) {
2096 	opt |= OPT_I;
2097     }
2098 
2099     u->prn = prn; /* 2015-03-10: this was conditional on OPT_V */
2100 
2101     *err = newton_raphson_max(b->val, u->ncoeff, maxit,
2102 			      crittol, gradtol,
2103 			      &iters, C_OTHER,
2104 			      user_get_criterion,
2105 			      (u->gg == NULL)? NULL : user_get_gradient,
2106 			      (u->gh == NULL)? NULL : user_get_hessian,
2107 			      u, opt, prn);
2108 
2109     if (!*err) {
2110 	ret = u->fx_out;
2111     }
2112 
2113  bailout:
2114 
2115     umax_destroy(u);
2116 
2117     return ret;
2118 }
2119 
deriv_free_optimize(MaxMethod method,gretl_matrix * b,const char * fncall,int maxit,double tol,int minimize,DATASET * dset,PRN * prn,int * err)2120 double deriv_free_optimize (MaxMethod method,
2121 			    gretl_matrix *b,
2122 			    const char *fncall,
2123 			    int maxit,
2124 			    double tol,
2125 			    int minimize,
2126 			    DATASET *dset,
2127 			    PRN *prn, int *err)
2128 {
2129     umax *u;
2130     gretlopt opt = OPT_NONE;
2131     double ret = NADBL;
2132 
2133     if (b->is_complex) {
2134 	*err = E_CMPLX;
2135 	return ret;
2136     }
2137 
2138     u = umax_new(GRETL_TYPE_DOUBLE);
2139     if (u == NULL) {
2140 	*err = E_ALLOC;
2141 	return ret;
2142     }
2143 
2144     u->ncoeff = gretl_vector_get_length(b);
2145     if (u->ncoeff == 0 || (method == ROOT_FIND && u->ncoeff != 2)) {
2146 	*err = E_INVARG;
2147 	goto bailout;
2148     }
2149 
2150     if (method != ROOT_FIND) {
2151 	u->b = b;
2152     }
2153 
2154     *err = user_gen_setup(u, fncall, NULL, NULL, dset);
2155     if (*err) {
2156 	return NADBL;
2157     }
2158 
2159     if (libset_get_int(MAX_VERBOSE)) {
2160 	opt = OPT_V;
2161 	u->prn = prn;
2162     }
2163 
2164     if (minimize) {
2165 	opt |= OPT_I;
2166     }
2167 
2168     if (method == SIMANN_MAX) {
2169 	*err = gretl_simann(b->val, u->ncoeff, maxit,
2170 			    user_get_criterion, u,
2171 			    opt, prn);
2172     } else if (method == NM_MAX) {
2173 	*err = gretl_amoeba(b->val, u->ncoeff, maxit,
2174 			    user_get_criterion, u,
2175 			    opt, prn);
2176     } else if (method == GSS_MAX) {
2177 	int iters = 0;
2178 
2179 	*err = gretl_gss(b->val, tol, &iters,
2180 			 user_get_criterion, u,
2181 			 opt, prn);
2182     } else if (method == ROOT_FIND) {
2183 	*err = gretl_fzero(b->val, tol,
2184 			   user_get_criterion2, u,
2185 			   &ret, opt, prn);
2186     }
2187 
2188     if (!*err && method != ROOT_FIND) {
2189 	ret = user_get_criterion(b->val, u);
2190     }
2191 
2192  bailout:
2193 
2194     umax_destroy(u);
2195 
2196     return ret;
2197 }
2198 
2199 #define JAC_DEBUG 0
2200 
user_calc_fvec(int m,int n,double * x,double * fvec,int * iflag,void * p)2201 static int user_calc_fvec (int m, int n, double *x, double *fvec,
2202 			   int *iflag, void *p)
2203 {
2204     umax *u = (umax *) p;
2205     gretl_matrix *v;
2206     int i, err;
2207 
2208     for (i=0; i<n; i++) {
2209 	u->b->val[i] = x[i];
2210     }
2211 
2212 #if JAC_DEBUG
2213     gretl_matrix_print(u->b, "user_calc_fvec: u->b");
2214 #endif
2215 
2216     err = execute_genr(u->gf, u->dset, u->prn);
2217     if (err) {
2218 	fprintf(stderr, "execute_genr: err = %d\n", err);
2219     }
2220 
2221     if (err) {
2222 	*iflag = -1;
2223 	return 0;
2224     }
2225 
2226     v = genr_get_output_matrix(u->gf);
2227 
2228 #if JAC_DEBUG
2229     gretl_matrix_print(v, "matrix from u->f");
2230 #endif
2231 
2232     if (v == NULL || gretl_vector_get_length(v) != m) {
2233 	fprintf(stderr, "user_calc_fvec: got bad matrix\n");
2234 	*iflag = -1;
2235     } else {
2236 	for (i=0; i<m; i++) {
2237 	    fvec[i] = v->val[i];
2238 	}
2239     }
2240 
2241     return 0;
2242 }
2243 
fdjac_allocate(int m,int n,gretl_matrix ** J,double ** w,double ** f)2244 static int fdjac_allocate (int m, int n,
2245 			   gretl_matrix **J,
2246 			   double **w, double **f)
2247 {
2248     *J = gretl_matrix_alloc(m, n);
2249     if (*J == NULL) {
2250 	return E_ALLOC;
2251     }
2252 
2253     *w = malloc(m * sizeof **w);
2254     *f = malloc(m * sizeof **f);
2255 
2256     if (*w == NULL || *f == NULL) {
2257 	return E_ALLOC;
2258     }
2259 
2260     return 0;
2261 }
2262 
user_fdjac(gretl_matrix * theta,const char * fncall,double eps,DATASET * dset,int * err)2263 gretl_matrix *user_fdjac (gretl_matrix *theta, const char *fncall,
2264 			  double eps, DATASET *dset, int *err)
2265 {
2266     umax *u;
2267     gretl_matrix *J = NULL;
2268     int m, n, nnf = 0;
2269     int iflag = 0;
2270     double *wa = NULL;
2271     double *fvec = NULL;
2272     int i;
2273 
2274     *err = 0;
2275 
2276     u = umax_new(GRETL_TYPE_MATRIX);
2277     if (u == NULL) {
2278 	*err = E_ALLOC;
2279 	return NULL;
2280     }
2281 
2282     n = gretl_vector_get_length(theta);
2283     if (n == 0) {
2284 	fprintf(stderr, "fdjac: gretl_vector_get_length gave %d for theta\n",
2285 		n);
2286 	*err = E_DATA;
2287 	return NULL;
2288     }
2289 
2290     u->b = theta;
2291     u->ncoeff = n;
2292 
2293     *err = user_gen_setup(u, fncall, NULL, NULL, dset);
2294     if (*err) {
2295 	fprintf(stderr, "fdjac: error %d from user_gen_setup\n", *err);
2296 	goto bailout;
2297     }
2298 
2299     if (u->fm_out == NULL) {
2300 	fprintf(stderr, "fdjac: u.fm_out is NULL\n");
2301 	*err = E_DATA; /* FIXME */
2302 	goto bailout;
2303     }
2304 
2305     m = gretl_vector_get_length(u->fm_out);
2306     if (m == 0) {
2307 	*err = E_DATA;
2308 	goto bailout;
2309     }
2310 
2311     *err = fdjac_allocate(m, n, &J, &wa, &fvec);
2312     if (*err) {
2313 	goto bailout;
2314     }
2315 
2316     for (i=0; i<m; i++) {
2317 	fvec[i] = u->fm_out->val[i];
2318 	if (na(fvec[i])) {
2319 	    nnf++;
2320 	}
2321     }
2322 
2323     if (nnf > 0) {
2324 	gretl_errmsg_sprintf("fdjac: got %d non-finite value(s) on input",
2325 			     nnf);
2326 	*err = E_DATA;
2327     } else {
2328 	int quality = libset_get_int(FDJAC_QUAL);
2329 
2330 	fdjac2_(user_calc_fvec, m, n, quality, theta->val, fvec, J->val,
2331 		m, &iflag, eps, wa, u);
2332     }
2333 
2334  bailout:
2335 
2336     free(wa);
2337     free(fvec);
2338 
2339     if (*err) {
2340 	gretl_matrix_free(J);
2341 	J = NULL;
2342     }
2343 
2344     umax_destroy(u);
2345 
2346     return J;
2347 }
2348 
user_numhess(gretl_matrix * b,const char * fncall,double d,DATASET * dset,int * err)2349 gretl_matrix *user_numhess (gretl_matrix *b, const char *fncall,
2350 			    double d, DATASET *dset, int *err)
2351 {
2352     gretl_matrix *H = NULL;
2353     struct uhess_data uh = {0};
2354     gchar *formula = NULL;
2355     int n;
2356 
2357     if (get_user_var_by_data(b) == NULL) {
2358 	fprintf(stderr, "numhess: b must be a named matrix\n");
2359 	*err = E_DATA;
2360 	return NULL;
2361     }
2362 
2363     n = gretl_vector_get_length(b);
2364     if (n == 0) {
2365 	fprintf(stderr, "numhess: gretl_vector_get_length gave %d for b\n", n);
2366 	*err = E_DATA;
2367 	return NULL;
2368     }
2369 
2370     if (!*err) {
2371 	formula = g_strdup_printf("$umax=%s", fncall);
2372 	uh.genr = genr_compile(formula, dset, GRETL_TYPE_DOUBLE, OPT_P,
2373 			       NULL, err);
2374     }
2375 
2376     if (*err) {
2377 	fprintf(stderr, "numhess: error %d from genr_compile\n", *err);
2378     } else {
2379 	H = gretl_zero_matrix_new(n, n);
2380 	if (H == NULL) {
2381 	    *err = E_ALLOC;
2382 	}
2383     }
2384 
2385     if (!*err) {
2386 	uh.dset = dset;
2387 	*err = numerical_hessian(b->val, H, uhess_callback,
2388 				 &uh, 0, d);
2389     }
2390 
2391     g_free(formula);
2392     user_var_delete_by_name("$umax", NULL);
2393     destroy_genr(uh.genr);
2394 
2395     if (*err && H != NULL) {
2396 	gretl_matrix_free(H);
2397 	H = NULL;
2398     }
2399 
2400     return H;
2401 }
2402 
2403 /* Below: Newton-Raphson code, starting with a few
2404    auxiliary functions */
2405 
broken_matrix(const gretl_matrix * m)2406 static int broken_matrix (const gretl_matrix *m)
2407 {
2408     int i, n = m->rows * m->cols;
2409 
2410     for (i=0; i<n; i++) {
2411 	if (na(m->val[i])) {
2412 	    return 1;
2413 	}
2414     }
2415 
2416     return 0;
2417 }
2418 
copy_to(double * targ,const double * src,int n)2419 static void copy_to (double *targ, const double *src, int n)
2420 {
2421     int i;
2422 
2423     for (i=0; i<n; i++) {
2424 	targ[i] = src[i];
2425     }
2426 }
2427 
copy_plus(double * targ,const double * src,double step,const double * a,int n)2428 static void copy_plus (double *targ, const double *src,
2429 		       double step, const double *a, int n)
2430 {
2431     int i;
2432 
2433     for (i=0; i<n; i++) {
2434 	targ[i] = src[i] + step * a[i];
2435     }
2436 }
2437 
scalar_xpx(const gretl_matrix * m)2438 static double scalar_xpx (const gretl_matrix *m)
2439 {
2440     double xpx = 0.0;
2441     int i;
2442 
2443     for (i=0; i<m->rows; i++) {
2444 	xpx += m->val[i] * m->val[i];
2445     }
2446 
2447     return xpx;
2448 }
2449 
2450 enum {
2451     GRADTOL_MET = 1,
2452     CRITTOL_MET,
2453     STEPMIN_MET
2454 };
2455 
print_NR_status(int status,double crittol,double gradtol,double sumgrad,PRN * prn)2456 static void print_NR_status (int status, double crittol, double gradtol,
2457 			     double sumgrad, PRN *prn)
2458 {
2459     int msgs = gretl_messages_on();
2460 
2461     if (status == GRADTOL_MET) {
2462 	if (msgs) {
2463 	    pprintf(prn, _("Gradient within tolerance (%g)\n"), gradtol);
2464 	}
2465     } else if (status == CRITTOL_MET) {
2466 	if (msgs) {
2467 	    pprintf(prn, _("Successive criterion values within tolerance (%g)\n"),
2468 		    crittol);
2469 	}
2470     } else if (status == STEPMIN_MET) {
2471 	if (sumgrad > 0) {
2472 	    pprintf(prn, _("Warning: couldn't improve criterion (gradient = %g)\n"),
2473 		    sumgrad);
2474 	} else {
2475 	    pprintf(prn, _("Warning: couldn't improve criterion\n"));
2476 	}
2477     }
2478 }
2479 
2480 /*
2481    The strategy here may be simplistic, but appears to be effective in
2482    quite a few cases: If the (negative) Hessian is not pd, we try to
2483    nudge it towards positive definiteness without losing too much
2484    information on curvature by downsizing the off-diagonal elements of
2485    H. In practice, we use
2486 
2487    C = \lambda H + (1-lambda) diag(H)
2488 
2489    where lambda is reasonably close to 1. Note that, if lambda was 0,
2490    a NR iteration would just amount to an iteration of the simple
2491    gradient method (on a scaled version of the coefficients).
2492    Hopefully, a few of those should be able to "tow us away" from the
2493    non-pd region. In desperate cases, we use the a diagonal matrix
2494    with the absolute values of H_{i,i} plus one.
2495 */
2496 
NR_invert_hessian(gretl_matrix * H,const gretl_matrix * Hcpy)2497 static int NR_invert_hessian (gretl_matrix *H, const gretl_matrix *Hcpy)
2498 {
2499     double hii, hmin = 1.0e-28; /* was 1.0e-20 */
2500     int i, j, n = H->rows;
2501     int restore = 0;
2502     double x;
2503     int err = 0;
2504 
2505     /* first, check if all the elements along the diagonal are
2506        numerically positive
2507     */
2508     for (i=0; i<n && !err; i++) {
2509 	hii = gretl_matrix_get(H, i, i);
2510 	if (hii < hmin) {
2511 	    err = 1;
2512 	    break;
2513 	}
2514     }
2515 
2516     if (err) {
2517 	fprintf(stderr, "NR_invert_hessian: non-positive "
2518 		"diagonal (H(%d,%d) = %g)\n", i+1, i+1, hii);
2519     } else {
2520 	err = gretl_invert_symmetric_matrix(H);
2521 
2522 	if (err == E_NOTPD) {
2523 	    double lambda = 1.0;
2524 	    int s;
2525 
2526 	    for (s=0; lambda > 0.1 && err; s++) {
2527 		lambda *= 0.8;
2528 		fprintf(stderr, "newton hessian fixup: round %d, lambda=%g\n",
2529 			s, lambda);
2530 		/* restore the original H */
2531 		gretl_matrix_copy_values(H, Hcpy);
2532 		for (i=0; i<n; i++) {
2533 		    for (j=0; j<i; j++) {
2534 			x = lambda * gretl_matrix_get(H, i, j);
2535 			gretl_matrix_set(H, i, j, x);
2536 			gretl_matrix_set(H, j, i, x);
2537 		    }
2538 		}
2539 		err = gretl_invert_symmetric_matrix(H);
2540 	    }
2541 	    restore = (err != 0);
2542 	}
2543     }
2544 
2545     if (err) {
2546 	fprintf(stderr, "NR_invert_hessian: major surgery needed\n");
2547 	if (restore) {
2548 	    gretl_matrix_copy_values(H, Hcpy);
2549 	}
2550 	for (i=0; i<n; i++) {
2551 	    for (j=0; j<n; j++) {
2552 		x = (i==j) ? 1/(1 + fabs(gretl_matrix_get(H, i, j))): 0;
2553 		gretl_matrix_set(H, i, j, x);
2554 	    }
2555 	}
2556     }
2557 
2558     return 0;
2559 }
2560 
2561 /**
2562  * newton_raphson_max:
2563  * @b: array of adjustable coefficients.
2564  * @n: number elements in array @b.
2565  * @maxit: the maximum number of iterations to allow.
2566  * @crittol: tolerance for terminating iteration, in terms of
2567  * the change in the criterion.
2568  * @gradtol: tolerance for terminating iteration, in terms of
2569  * the gradient.
2570  * @itercount: location to receive count of iterations.
2571  * @crittype: code for type of the maximand/minimand: should
2572  * be %C_LOGLIK, %C_GMM or %C_OTHER.  Used only in printing
2573  * iteration info.
2574  * @cfunc: pointer to function used to calculate maximand.
2575  * @gradfunc: pointer to function used to calculate the
2576  * gradient, or %NULL for default numerical calculation.
2577  * @hessfunc: pointer to function used to calculate the
2578  * Hessian.
2579  * @data: pointer that will be passed as the last
2580  * parameter to the callback functions @cfunc, @gradfunc
2581  * and @hessfunc.
2582  * @opt: may contain %OPT_V for verbose operation.
2583  * @prn: printing struct (or %NULL).  Only used if @opt
2584  * includes %OPT_V.
2585  *
2586  * The functions @cfunc (computes the criterion, usually a
2587  * loglikelihood) and @gradfunc (score, provides an updated
2588  * estimate of the gradient in its second argument) are just as in
2589  * BFGS_max above.
2590  *
2591  * The @hessfunc callback should compute the negative Hessian,
2592  * _not_ inverted; newton_raphson_max takes care of the inversion,
2593  * with a routine for fixing up the matrix if it's not positive
2594  * definite. If @hessfunc is NULL we fall back on a numerical
2595  * approximation to the Hessian.
2596  *
2597  * Returns: 0 on successful completion, non-zero error code
2598  * on error.
2599  */
2600 
newton_raphson_max(double * b,int n,int maxit,double crittol,double gradtol,int * itercount,int crittype,BFGS_CRIT_FUNC cfunc,BFGS_GRAD_FUNC gradfunc,HESS_FUNC hessfunc,void * data,gretlopt opt,PRN * prn)2601 int newton_raphson_max (double *b, int n, int maxit,
2602 			double crittol, double gradtol,
2603 			int *itercount, int crittype,
2604 			BFGS_CRIT_FUNC cfunc,
2605 			BFGS_GRAD_FUNC gradfunc,
2606 			HESS_FUNC hessfunc,
2607 			void *data, gretlopt opt,
2608 			PRN *prn)
2609 {
2610     BFGS_GRAD_FUNC realgrad = NULL;
2611     int verbose = (opt & OPT_V);
2612     int minimize = (opt & OPT_I);
2613     double stepmin = 1.0e-6;
2614     gretl_matrix_block *B;
2615     gretl_matrix *H0, *H1;
2616     gretl_matrix *g, *a;
2617     double *b0, *b1;
2618     double f0, f1, sumgrad = 0;
2619     double steplen = 1.0;
2620     int status = 0;
2621     int iter = 0;
2622     int err = 0;
2623 
2624     b0 = malloc(2 * n * sizeof *b0);
2625     if (b0 == NULL) {
2626 	return E_ALLOC;
2627     }
2628 
2629     B = gretl_matrix_block_new(&H0, n, n,
2630 			       &H1, n, n,
2631 			       &g, n, 1,
2632 			       &a, n, 1,
2633 			       NULL);
2634     if (B == NULL) {
2635 	free(b0);
2636 	return E_ALLOC;
2637     }
2638 
2639     if (gradfunc == NULL) {
2640 	gradfunc = numeric_gradient;
2641     } else {
2642 	realgrad = gradfunc;
2643     }
2644 
2645     /* needs some work */
2646     optim_get_user_values(b, n, NULL, NULL, NULL, opt, prn);
2647 
2648     b1 = b0 + n;
2649     copy_to(b1, b, n);
2650 
2651     f1 = optim_fncall(cfunc, b1, data, minimize);
2652     if (na(f1)) {
2653 	gretl_errmsg_set(_("Initial value of objective function is not finite"));
2654 	err = E_NAN;
2655     }
2656 
2657     if (!err) {
2658 	err = optim_gradcall(gradfunc, b, g->val, n, cfunc, data, minimize);
2659 	if (err) {
2660 	    fprintf(stderr, "newton_raphson_max: err = %d from %s\n", err,
2661 		    realgrad ? "supplied gradfunc" : "numeric_gradient");
2662 	}
2663     }
2664 
2665     if (!err) {
2666 	if (hessfunc != NULL) {
2667 	    err = hessfunc(b, H1, data);
2668 	} else {
2669 	    err = NR_fallback_hessian(b, H1, realgrad, cfunc, data);
2670 	}
2671 	if (!err) {
2672 	    if (minimize) {
2673 		gretl_matrix_multiply_by_scalar(H1, -1.0);
2674 	    }
2675 	    gretl_matrix_copy_values(H0, H1);
2676 	    err = NR_invert_hessian(H1, H0);
2677 	}
2678     }
2679 
2680     gretl_iteration_push();
2681 
2682     while (status == 0 && !err) {
2683 	iter++;
2684 	steplen = 1.0;
2685 	f0 = f1;
2686 
2687 	copy_to(b0, b1, n);
2688 
2689 	if (broken_matrix(g)) {
2690 	    fprintf(stderr, "NA in gradient\n");
2691 	    err = E_NAN;
2692 	    break;
2693 	}
2694 
2695 	gretl_matrix_copy_values(H0, H1);
2696 	if (broken_matrix(H0)) {
2697 	    fprintf(stderr, "NA in Hessian\n");
2698 	    err = E_NAN;
2699 	    break;
2700 	}
2701 
2702 	/* apply quadratic approximation */
2703 	gretl_matrix_multiply(H0, g, a);
2704 	copy_plus(b1, b0, steplen, a->val, n);
2705 	f1 = optim_fncall(cfunc, b1, data, minimize);
2706 
2707 	while (na(f1) || ((f1 < f0) && (steplen > stepmin))) {
2708 	    /* try smaller step */
2709 	    steplen /= 2.0;
2710 	    copy_plus(b1, b0, steplen, a->val, n);
2711 	    f1 = optim_fncall(cfunc, b1, data, minimize);
2712 	}
2713 
2714 	if (verbose) {
2715 	    print_iter_info(iter, f1, crittype, n, b1, g->val,
2716 			    steplen, prn);
2717 	}
2718 
2719 	err = optim_gradcall(gradfunc, b1, g->val, n, cfunc, data,
2720 			     minimize);
2721 
2722 	if (err || broken_matrix(g)) {
2723 	    err = (err == 0)? E_NAN : err;
2724 	    break;
2725 	}
2726 
2727 	if (hessfunc != NULL) {
2728 	    err = hessfunc(b1, H1, data);
2729 	} else {
2730 	    err = NR_fallback_hessian(b1, H1, realgrad, cfunc, data);
2731 	}
2732 
2733 	if (err || broken_matrix(H1)) {
2734 	    err = (err == 0)? E_NAN : err;
2735 	    break;
2736 	}
2737 
2738 	if (!err) {
2739 	    if (minimize) {
2740 		gretl_matrix_multiply_by_scalar(H1, -1.0);
2741 	    }
2742 	    gretl_matrix_copy_values(H0, H1);
2743 	    err = NR_invert_hessian(H1, H0);
2744 	    if (err) {
2745 		break;
2746 	    }
2747 	}
2748 
2749 	sumgrad = sqrt(scalar_xpx(g));
2750 
2751 	if (steplen < stepmin) {
2752 	    status = STEPMIN_MET;
2753 	} else if (iter > maxit) {
2754 	    err = E_NOCONV;
2755 	} else if (sumgrad < gradtol) {
2756 	    status = GRADTOL_MET;
2757 	} else if (f1 - f0 < crittol) {
2758 	    status = CRITTOL_MET;
2759 	}
2760     }
2761 
2762     gretl_iteration_pop();
2763 
2764     if (verbose) {
2765 	print_iter_info(-1, f1, crittype, n, b1, g->val,
2766 			steplen, prn);
2767 	pputc(prn, '\n');
2768     }
2769 
2770     *itercount = iter;
2771 
2772     if (!err) {
2773 	copy_to(b, b1, n);
2774 	if (prn != NULL) {
2775 	    print_NR_status(status, crittol, gradtol, sumgrad, prn);
2776 	}
2777     }
2778 
2779     free(b0);
2780     gretl_matrix_block_destroy(B);
2781 
2782     return err;
2783 }
2784 
simann_call(BFGS_CRIT_FUNC cfunc,double * b,void * data,int minimize)2785 static double simann_call (BFGS_CRIT_FUNC cfunc,
2786 			   double *b, void *data,
2787 			   int minimize)
2788 {
2789     double ret = cfunc(b, data);
2790 
2791     return na(ret) ? NADBL : minimize ? -ret : ret;
2792 }
2793 
2794 /**
2795  * gretl_simann:
2796  * @theta: parameter array.
2797  * @n: length of @theta.
2798  * @maxit: the maximum number of iterations to perform.
2799  * @cfunc: the function to be maximized.
2800  * @data: pointer to be passed to the @cfunc callback.
2801  * @opt: may include %OPT_V for verbose operation.
2802  * @prn: printing struct, or NULL.
2803  *
2804  * Simulated annealing: can help to improve the initialization
2805  * of @theta for numerical optimization. On exit the value of
2806  * @theta is set to the func-best point in case of improvement,
2807  * otherwise to the last point visited.
2808  *
2809  * Returns: 0 on success, non-zero code on error.
2810  */
2811 
gretl_simann(double * theta,int n,int maxit,BFGS_CRIT_FUNC cfunc,void * data,gretlopt opt,PRN * prn)2812 int gretl_simann (double *theta, int n, int maxit,
2813 		  BFGS_CRIT_FUNC cfunc, void *data,
2814 		  gretlopt opt, PRN *prn)
2815 {
2816     gretl_matrix b;
2817     gretl_matrix *b0 = NULL;
2818     gretl_matrix *b1 = NULL;
2819     gretl_matrix *bstar = NULL;
2820     gretl_matrix *d = NULL;
2821     double f0, f1;
2822     double fbest, fworst;
2823     double Temp = 1.0;
2824     double radius = 1.0;
2825     int improved = 0;
2826     int minimize;
2827     int i, err = 0;
2828 
2829     if (maxit <= 0) {
2830 	maxit = 1024;
2831     }
2832 
2833     /* maximize by default, but minimize if OPT_I is given */
2834     minimize = (opt & OPT_I)? 1 : 0;
2835 
2836     gretl_matrix_init_full(&b, n, 1, theta);
2837 
2838     b0 = gretl_matrix_copy(&b);
2839     b1 = gretl_matrix_copy(&b);
2840     bstar = gretl_matrix_copy(&b);
2841     d = gretl_column_vector_alloc(n);
2842 
2843     if (b0 == NULL || b1 == NULL || bstar == NULL || d == NULL) {
2844 	err = E_ALLOC;
2845 	goto bailout;
2846     }
2847 
2848     f0 = fbest = fworst = simann_call(cfunc, b.val, data, minimize);
2849 
2850     if (opt & OPT_V) {
2851 	pprintf(prn, "\nSimulated annealing: initial function value = %.8g\n",
2852 		f0);
2853     }
2854 
2855     gretl_iteration_push();
2856 
2857     /* Question: should the initial radius be a function of the scale
2858        of the initial parameter vector?
2859     */
2860 
2861     for (i=0; i<maxit; i++) {
2862 	gretl_matrix_random_fill(d, D_NORMAL);
2863 	gretl_matrix_multiply_by_scalar(d, radius);
2864 	gretl_matrix_add_to(b1, d);
2865 	f1 = simann_call(cfunc, b1->val, data, minimize);
2866 
2867 	if (!na(f1) && (f1 > f0 || gretl_rand_01() < Temp)) {
2868 	    /* jump to the new point */
2869 	    f0 = f1;
2870 	    gretl_matrix_copy_values(b0, b1);
2871 	    if (f0 > fbest) {
2872 		fbest = f0;
2873 		gretl_matrix_copy_values(bstar, b0);
2874 		if (opt & OPT_V) {
2875 		    if (!improved) {
2876 			pprintf(prn, "\n%6s %12s %12s %12s\n",
2877 				"iter", "temp", "radius", "fbest");
2878 		    }
2879 		    pprintf(prn, "%6d %#12.6g %#12.6g %#12.6g\n",
2880 			    i, Temp, radius, fbest);
2881 		}
2882 		improved = 1;
2883 	    } else if (f0 < fworst) {
2884 		fworst = f0;
2885 	    }
2886 	} else {
2887 	    /* revert to where we were */
2888 	    gretl_matrix_copy_values(b1, b0);
2889 	    f1 = f0;
2890 	}
2891 
2892 	Temp *= 0.999;
2893 	radius *= 0.9999;
2894     }
2895 
2896     gretl_iteration_pop();
2897 
2898     if (improved) {
2899 	/* use the best point */
2900 	gretl_matrix_copy_values(&b, bstar);
2901     } else {
2902 	/* use the last point */
2903 	gretl_matrix_copy_values(&b, b0);
2904     }
2905 
2906     if (improved) {
2907 	if (opt & OPT_V) pputc(prn, '\n');
2908     } else {
2909 	pprintf(prn, "No improvement found in %d iterations\n\n", maxit);
2910     }
2911 
2912     if (fbest - fworst < 1.0e-9) {
2913 	pprintf(prn, "*** warning: surface seems to be flat\n");
2914     }
2915 
2916  bailout:
2917 
2918     gretl_matrix_free(b0);
2919     gretl_matrix_free(b1);
2920     gretl_matrix_free(bstar);
2921     gretl_matrix_free(d);
2922 
2923     return err;
2924 }
2925 
2926 /*
2927   nelder_mead: this is based closely on the nelmin function as written
2928   in C by John Burkardt; see
2929   http://people.sc.fsu.edu/~jburkardt/c_src/asa047
2930   It is converted to a maximizer, and modified for use with the
2931   gretl library.
2932 
2933   Burkardt's code is distributed under the GNU LGPL license, and was
2934   last modified on 28 October 2010. It draws on original Fortran code
2935   by R. O'Neill, for which see "Algorithm AS 47: Function Minimization
2936   Using a Simplex Procedure", Journal of the Royal Statistical
2937   Society, Series C (Applied Statistics), Vol. 20, No. 3, 1971.
2938 */
2939 
nm_call(BFGS_CRIT_FUNC cfunc,double * b,void * data,int * ncalls,int minimize)2940 static double nm_call (BFGS_CRIT_FUNC cfunc,
2941 		       double *b, void *data,
2942 		       int *ncalls, int minimize)
2943 {
2944     double ret = cfunc(b, data);
2945 
2946     *ncalls += 1;
2947 
2948     return minimize ? ret : na(ret) ? ret : -ret;
2949 }
2950 
2951 static int
nelder_mead(BFGS_CRIT_FUNC cfunc,int n,double start[],double xmin[],double * ynewlo,double reqmin,double step[],int maxcalls,int * ncalls,int * nresets,void * data,gretlopt opt,PRN * prn)2952 nelder_mead (BFGS_CRIT_FUNC cfunc, int n, double start[],
2953 	     double xmin[], double *ynewlo, double reqmin,
2954 	     double step[], int maxcalls, int *ncalls, int *nresets,
2955 	     void *data, gretlopt opt, PRN *prn)
2956 {
2957     gretl_matrix *pmat = NULL;
2958     double ccoeff = 0.5;
2959     double ecoeff = 2.0;
2960     double rcoeff = 1.0;
2961     double eps = 0.001;
2962     double del = 1.0;
2963     double *wspace;
2964     double *p;
2965     double *p2star;
2966     double *pbar;
2967     double *pstar;
2968     double *y;
2969     double rq, x, z;
2970     double ylo, ystar, y2star;
2971     /* frequency of convergence check */
2972     int konvge = 10;
2973     int i, ihi, ilo;
2974     int l, j, jcount;
2975     int outer, inner;
2976     int getmin;
2977     int err = 0;
2978 
2979     /* use a gretl_matrix in case we want to print it */
2980     pmat = gretl_matrix_alloc(n, n + 1);
2981     wspace = malloc((4*n + 1) * sizeof *wspace);
2982 
2983     if (pmat == NULL || wspace == NULL) {
2984 	gretl_matrix_free(pmat);
2985 	free(wspace);
2986 	return E_ALLOC;
2987     }
2988 
2989     p = pmat->val;
2990     pstar = wspace;
2991     p2star = pstar + n;
2992     pbar = p2star + n;
2993     y = pbar + n;
2994 
2995     *ncalls = *nresets = 0;
2996     jcount = konvge;
2997     rq = reqmin * n;
2998 
2999     /* maximize by default, but minimize if OPT_I is given */
3000     getmin = (opt & OPT_I)? 1 : 0;
3001 
3002     gretl_iteration_push();
3003 
3004     for (outer=1; ; outer++) {
3005 	for (i=0; i<n; i++) {
3006 	    p[i+n*n] = start[i];
3007 	}
3008 	y[n] = nm_call(cfunc, start, data, ncalls, getmin);
3009 
3010 	if (opt & OPT_V) {
3011 	    if (outer == 1) {
3012 		pprintf(prn, "\nOuter iteration %d: function value = %#g\n",
3013 			outer, y[n]);
3014 	    } else {
3015 		pprintf(prn, "Outer iteration %d (reset)\n", outer);
3016 	    }
3017 	}
3018 
3019 	/* construct the simplex */
3020 	for (j=0; j<n; j++) {
3021 	    x = start[j];
3022 	    start[j] += step[j] * del;
3023 	    for (i=0; i<n; i++) {
3024 		p[i+j*n] = start[i];
3025 	    }
3026 	    y[j] = nm_call(cfunc, start, data, ncalls, getmin);
3027 	    start[j] = x;
3028 	}
3029 
3030 	/* find the lowest y value */
3031 	ylo = y[0];
3032 	ilo = 0;
3033 	for (i=1; i<=n; i++) {
3034 	    if (y[i] < ylo) {
3035 		ylo = y[i];
3036 		ilo = i;
3037 	    }
3038 	}
3039 
3040 	for (inner=1; *ncalls < maxcalls; inner++) {
3041 	    *ynewlo = y[0];
3042 	    ihi = 0;
3043 
3044 	    for (i=1; i<=n; i++) {
3045 		if (*ynewlo < y[i]) {
3046 		    *ynewlo = y[i];
3047 		    ihi = i;
3048 		}
3049 	    }
3050 	    /* calculate pbar, the centroid of the simplex */
3051 	    for (i=0; i<n; i++) {
3052 		z = 0.0;
3053 		for (j=0; j<=n; j++) {
3054 		    z += p[i+j*n];
3055 		}
3056 		z -= p[i+ihi*n];
3057 		pbar[i] = z / n;
3058 	    }
3059 
3060 	    /* reflection through the centroid */
3061 	    for (i=0; i<n; i++) {
3062 		pstar[i] = pbar[i] + rcoeff * (pbar[i] - p[i+ihi*n]);
3063 	    }
3064 	    ystar = nm_call(cfunc, pstar, data, ncalls, getmin);
3065 
3066 	    if ((opt & OPT_V) && (inner == 1 || inner % 10 == 0)) {
3067 		pprintf(prn, " inner iter %3d: function value %#g\n",
3068 			inner, ystar);
3069 	    }
3070 
3071 	    if (ystar < ylo) {
3072 		/* successful reflection, so extension */
3073 		for (i=0; i<n; i++) {
3074 		    p2star[i] = pbar[i] + ecoeff * (pstar[i] - pbar[i]);
3075 		}
3076 		y2star = nm_call(cfunc, p2star, data, ncalls, getmin);
3077 		/* check extension */
3078 		if (ystar < y2star) {
3079 		    for (i=0; i<n; i++) {
3080 			p[i+ihi*n] = pstar[i];
3081 		    }
3082 		    y[ihi] = ystar;
3083 		} else {
3084 		    for (i=0; i<n; i++) {
3085 			p[i+ihi*n] = p2star[i];
3086 		    }
3087 		    y[ihi] = y2star;
3088 		}
3089 	    } else {
3090 		l = 0;
3091 		for (i=0; i<=n; i++) {
3092 		    if (ystar < y[i]) {
3093 			l++;
3094 		    }
3095 		}
3096 		if (l > 1) {
3097 		    for (i=0; i<n; i++) {
3098 			p[i+ihi*n] = pstar[i];
3099 		    }
3100 		    y[ihi] = ystar;
3101 		} else if (l == 0) {
3102 		    for (i=0; i<n; i++) {
3103 			p2star[i] = pbar[i] + ccoeff * (p[i+ihi*n] - pbar[i]);
3104 		    }
3105 		    y2star = nm_call(cfunc, p2star, data, ncalls, getmin);
3106 		    /* contract the whole simplex */
3107 		    if (y[ihi] < y2star) {
3108 			for (j=0; j<=n; j++) {
3109 			    for (i=0; i<n; i++) {
3110 				p[i+j*n] = (p[i+j*n] + p[i+ilo*n]) * 0.5;
3111 				xmin[i] = p[i+j*n];
3112 			    }
3113 			    y[j] = nm_call(cfunc, xmin, data, ncalls, getmin);
3114 			}
3115 			ylo = y[0];
3116 			ilo = 0;
3117 			for (i=1; i<=n; i++) {
3118 			    if (y[i] < ylo) {
3119 				ylo = y[i];
3120 				ilo = i;
3121 			    }
3122 			}
3123 			continue;
3124 		    } else {
3125 			for (i=0; i<n; i++) {
3126 			    p[i+ihi*n] = p2star[i];
3127 			}
3128 			y[ihi] = y2star;
3129 		    }
3130 		} else if (l == 1) {
3131 		    for (i=0; i<n; i++) {
3132 			p2star[i] = pbar[i] + ccoeff * (pstar[i] - pbar[i]);
3133 		    }
3134 		    y2star = nm_call(cfunc, p2star, data, ncalls, getmin);
3135 		    /* retain reflection? */
3136 		    if (y2star <= ystar) {
3137 			for (i=0; i<n; i++) {
3138 			    p[i+ihi*n] = p2star[i];
3139 			}
3140 			y[ihi] = y2star;
3141 		    } else {
3142 			for (i=0; i<n; i++) {
3143 			    p[i+ihi*n] = pstar[i];
3144 			}
3145 			y[ihi] = ystar;
3146 		    }
3147 		}
3148 	    }
3149 
3150 	    /* check if ylo improved */
3151 	    if (y[ihi] < ylo) {
3152 		ylo = y[ihi];
3153 		ilo = ihi;
3154 	    }
3155 	    jcount--;
3156 
3157 	    if (jcount > 0) {
3158 		continue;
3159 	    }
3160 
3161 	    /* check to see if optimum reached */
3162 	    if (*ncalls <= maxcalls) {
3163 		jcount = konvge;
3164 		z = 0.0;
3165 		for (i=0; i<=n; i++) {
3166 		    z += y[i];
3167 		}
3168 		x = z / (n+1);
3169 		z = 0.0;
3170 		for (i=0; i<=n; i++) {
3171 		    z += (y[i] - x) * (y[i] - x);
3172 		}
3173 		if (z <= rq) {
3174 		    break;
3175 		}
3176 	    }
3177 	}
3178 
3179 	/* check that ynewlo is a local minimum */
3180 	for (i=0; i<n; i++) {
3181 	    xmin[i] = p[i+ilo*n];
3182 	}
3183 	*ynewlo = y[ilo];
3184 
3185 	if (*ncalls > maxcalls) {
3186 	    err = E_NOCONV;
3187 	    break;
3188 	}
3189 
3190 	err = 0;
3191 
3192 	for (i=0; i<n; i++) {
3193 	    double xsave = xmin[i];
3194 	    double dx = step[i] * eps;
3195 
3196 	    xmin[i] = xsave + dx;
3197 	    z = nm_call(cfunc, xmin, data, ncalls, getmin);
3198 	    if (z < *ynewlo) {
3199 		err = E_NOCONV;
3200 		break;
3201 	    }
3202 	    xmin[i] = xsave - dx;
3203 	    z = nm_call(cfunc, xmin, data, ncalls, getmin);
3204 	    if (z < *ynewlo) {
3205 		err = E_NOCONV;
3206 		break;
3207 	    }
3208 	    xmin[i] = xsave;
3209 	}
3210 
3211 	if (err == 0) {
3212 	    if (opt & OPT_V) {
3213 		double crit = getmin ? *ynewlo : -(*ynewlo);
3214 
3215 		pprintf(prn, "Found optimum %#g after %d function calls, "
3216 			"%d resets\n\n", crit, *ncalls, *nresets);
3217 	    }
3218 	    break;
3219 	}
3220 
3221 	/* prepare to restart */
3222 	for (i=0; i<n; i++) {
3223 	    start[i] = xmin[i];
3224 	}
3225 	del = eps;
3226 	*nresets += 1;
3227     }
3228 
3229     gretl_iteration_pop();
3230 
3231     gretl_matrix_free(pmat);
3232     free(wspace);
3233 
3234     return err;
3235 }
3236 
gretl_amoeba(double * theta,int n,int maxit,BFGS_CRIT_FUNC cfunc,void * data,gretlopt opt,PRN * prn)3237 int gretl_amoeba (double *theta, int n, int maxit,
3238 		  BFGS_CRIT_FUNC cfunc, void *data,
3239 		  gretlopt opt, PRN *prn)
3240 {
3241     int ncalls = 0;
3242     int nresets = 0;
3243     int maxcalls;
3244     double reqmin = 1.0e-12;
3245     double fval = 0.0;
3246     double *step;
3247     double *xmin;
3248     int i, err = 0;
3249 
3250     step = malloc(n * sizeof *step);
3251     xmin = malloc(n * sizeof *xmin);
3252 
3253     if (step == NULL || xmin == NULL) {
3254 	free(step); free(xmin);
3255 	return E_ALLOC;
3256     }
3257 
3258     for (i=0; i<n; i++) {
3259 	step[i] = 1.0;
3260 	xmin[i] = 0.0;
3261     }
3262 
3263     if (maxit < 0) {
3264 	maxcalls = -maxit;
3265 	opt |= OPT_F; /* fail on non-convergence */
3266     } else {
3267 	maxcalls = maxit == 0 ? 2000 : maxit;
3268     }
3269 
3270     err = nelder_mead(cfunc, n, theta, xmin, &fval, reqmin,
3271 		      step, maxcalls, &ncalls, &nresets,
3272 		      data, opt, prn);
3273 
3274     fprintf(stderr, "asa047: fncalls=%d, err=%d\n", ncalls, err);
3275 
3276     if (err == E_NOCONV && !(opt & OPT_F)) {
3277 	/* tolerate non-convergence */
3278 	err = 0;
3279     }
3280 
3281     if (!err) {
3282 	for (i=0; i<n; i++) {
3283 	    theta[i] = xmin[i];
3284 	}
3285     }
3286 
3287     free(step);
3288     free(xmin);
3289 
3290     return err;
3291 }
3292 
gretl_gss(double * theta,double tol,int * ic,BFGS_CRIT_FUNC cfunc,void * data,gretlopt opt,PRN * prn)3293 int gretl_gss (double *theta, double tol, int *ic,
3294 	       BFGS_CRIT_FUNC cfunc, void *data,
3295 	       gretlopt opt, PRN *prn)
3296 {
3297     double gr = (sqrt(5.0) + 1) / 2.0;
3298     double a = theta[1];
3299     double b = theta[2];
3300     double c = b - (b - a) / gr;
3301     double d = a + (b - a) / gr;
3302     double fc, fd;
3303     int minimize = (opt & OPT_I);
3304     int cond, iter = 1;
3305     int err = 0;
3306 
3307     if (na(tol)) {
3308 	tol = 1.0e-4; /* ?? */
3309     }
3310 
3311     while (fabs(c - d) > tol) {
3312 	theta[0] = c;
3313 	fc = cfunc(theta, data);
3314 	theta[0] = d;
3315 	fd = cfunc(theta, data);
3316 	if (opt & OPT_V) {
3317 	    pprintf(prn, "%d: bracket={%g,%g}, values={%g,%g}\n",
3318 		    iter, c, d, fc, fd);
3319 	}
3320 	if (na(fc) || na(fd)) {
3321 	    err = E_NAN;
3322 	    break;
3323 	}
3324 	cond = minimize ? fc < fd : fc > fd;
3325 	if (cond) {
3326             b = d;
3327         } else {
3328             a = c;
3329 	}
3330 	/* recompute c and d to preserve precision */
3331 	c = b - (b - a) / gr;
3332 	d = a + (b - a) / gr;
3333 	iter++;
3334     }
3335 
3336     if (ic != NULL) {
3337 	*ic = iter;
3338     }
3339 
3340     if (!err) {
3341 	/* record the optimum and the bracket */
3342 	theta[0] = (b + a) / 2;
3343 	theta[1] = a;
3344 	theta[2] = b;
3345     }
3346 
3347     return err;
3348 }
3349 
sgn(double x)3350 static int sgn (double x)
3351 {
3352     return x == 0 ? 0 : x < 0 ? -1 : 1;
3353 }
3354 
3355 /* Try to find a value for x1 which brackets a zero-crossing.
3356    Based on Octave's fzero.m but with a little extra stuff.
3357 */
3358 
find_x1(double x0,double y0,double * py1,ZFUNC zfunc,void * data)3359 static double find_x1 (double x0, double y0, double *py1,
3360 		       ZFUNC zfunc, void *data)
3361 {
3362     double srch[] = {
3363         -0.01, 0.025, -0.05, 0.10, -0.25, 0.50,
3364         -1.01, 2.5, -5, 10, -50, 100, -500, 1000
3365     };
3366     double x1, y1, a = x0;
3367     int warnsave, negbad = 0;
3368     int i;
3369 
3370     warnsave = libset_get_bool(WARNINGS);
3371     libset_set_bool(WARNINGS, 0);
3372 
3373     if (fabs(x0) < 0.001) {
3374 	a = (x0 == 0)? 0.1 : sgn(x0) * 0.1;
3375     }
3376 
3377     errno = 0;
3378     *py1 = NADBL;
3379 
3380     for (i=0; i<G_N_ELEMENTS(srch); i++) {
3381 	x1 = a + a * srch[i];
3382 	if (negbad && x1 < 0) {
3383 	    x1 = -x1;
3384 	}
3385 	y1 = zfunc(x1, data);
3386 	if (na(y1)) {
3387 	    if (errno == EDOM && x1 < 0) {
3388 		negbad = 1;
3389 	    }
3390 	    errno = 0;
3391 	} else if (sgn(y1) * sgn(y0) <= 0) {
3392 	    /* found a candidate */
3393 	    *py1 = y1;
3394 	    break;
3395 	}
3396     }
3397 
3398     libset_set_bool(WARNINGS, warnsave);
3399 
3400     return na(*py1) ? NADBL : x1;
3401 }
3402 
gretl_fzero(double * bracket,double tol,ZFUNC zfunc,void * data,double * px,gretlopt opt,PRN * prn)3403 int gretl_fzero (double *bracket, double tol,
3404 		 ZFUNC zfunc, void *data, double *px,
3405 		 gretlopt opt, PRN *prn)
3406 {
3407     int MAXITER = 80;
3408     double ytol = 1.0e-14;
3409     double xtol = 1.0e-15;
3410     double y, y0, y1, y2;
3411     double x, x0, x1, x2;
3412     double dx, d0, d1;
3413     int i, err = 0;
3414 
3415     x0 = bracket[0];
3416     x1 = bracket[1];
3417 
3418     if (!na(tol)) {
3419 	ytol = tol;
3420     }
3421     if (na(x0)) {
3422 	/* exact zero is too risky as default */
3423 	x0 = 0.107;
3424     }
3425 
3426     y0 = zfunc(x0, data);
3427     if (na(y0)) {
3428 	return E_NAN;
3429     }
3430     if (!na(x1)) {
3431 	y1 = zfunc(x1, data);
3432 	if (na(y1)) {
3433 	    return E_NAN;
3434 	}
3435     } else {
3436 	x1 = find_x1(x0, y0, &y1, zfunc, data);
3437 	if (na(x1)) {
3438 	    return E_NOCONV;
3439 	}
3440     }
3441 
3442     if (y0 == 0) {
3443 	*px = x0;
3444 	return 0;
3445     } else if (y1 == 0) {
3446 	*px = x1;
3447 	return 0;
3448     } else if (y0 * y1 > 0) {
3449 	return E_NOCONV;
3450     }
3451 
3452     if (opt & OPT_V) {
3453 	pprintf(prn, "Initial bracket {%#.6g, %#.6g}\n", x0, x1);
3454     }
3455 
3456     for (i=0; i<MAXITER && !err; i++) {
3457         x2 = (x0 + x1) / 2;
3458 	y2 = zfunc(x2, data);
3459 	/* exponential interpolation of x */
3460         x = x2 + (x2-x0) * sgn(y0-y1)*y2 / sqrt(y2*y2 - y0*y1);
3461 	d0 = fabs(x-x0);
3462 	d1 = fabs(x-x1);
3463 	dx = d0 < d1 ? d0 : d1;
3464 	y = zfunc(x, data);
3465 	if (opt & OPT_V) {
3466 	    pprintf(prn, "Iter %2d: f(%#.9g) = %g\n", i+1, x, y);
3467 	}
3468         if (dx < xtol || fabs(y) < ytol) {
3469             break;
3470 	}
3471         if (sgn(y2) != sgn(y)) {
3472             x0 = x2;
3473 	    y0 = y2;
3474 	    x1 = x;
3475 	    y1 = y;
3476         } else if (sgn(y1) != sgn(y)) {
3477             x0 = x;
3478             y0 = y;
3479         } else {
3480             x1 = x;
3481             y1 = y;
3482         }
3483     }
3484 
3485     if (!err && fabs(y) > ytol) {
3486 	x = NADBL;
3487 	err = E_NOCONV;
3488     }
3489 
3490     if (!err) {
3491 	/* record the root */
3492 	*px = x;
3493     }
3494 
3495     return err;
3496 }
3497