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 /* Nonlinear least squares for libgretl, using minpack; also Maximum
21    Likelihood and GMM estimation using BFGS.  However, much of the
22    GMM-specific material is in the companion file, gmm.c
23 */
24 
25 #include "libgretl.h"
26 #include "libset.h"
27 #include "uservar.h"
28 #include "matrix_extra.h"
29 #include "gretl_func.h"
30 #include "nlspec.h"
31 #include "cmd_private.h"
32 #include "estim_private.h"
33 #include "gretl_bfgs.h"
34 #include "tsls.h"
35 
36 #include "../../minpack/minpack.h"
37 #include <float.h>
38 
39 /**
40  * SECTION:nls
41  * @short_description: estimation of nonlinear models
42  * @title: Nonlinear models
43  * @include: libgretl.h
44  *
45  * Provides mechanisms for estimating nonlinear models via
46  * Nonlinear Least Squares, Maximum Likelihood, or GMM.
47  */
48 
49 #define NLS_DEBUG 0
50 #define ML_DEBUG 0
51 #define GRAD_DEBUG 0
52 
53 struct parm_ {
54     char name[VNAMELEN];  /* name of parameter */
55     gretl_bundle *bundle; /* parent bundle, if applicable */
56     int type;             /* type of parameter (scalar or vector) */
57     int dvtype;           /* type of derivative for parameter */
58     char *deriv;          /* string representation of derivative of regression
59 			     function with respect to param (or NULL) */
60     int dnum;             /* ID number of series holding the derivative, or 0 */
61     int nc;               /* number of individual coefficients associated
62 			     with the parameter */
63     char dname[VNAMELEN]; /* name of variable holding the derivative */
64     GENERATOR *dgenr;     /* generator for derivative */
65     gretl_matrix *vec;    /* pointer to vector parameter */
66 };
67 
68 #define scalar_param(s,i) (s->params[i].type == GRETL_TYPE_DOUBLE)
69 #define matrix_deriv(s,i) (s->params[i].dvtype == GRETL_TYPE_MATRIX)
70 #define scalar_deriv(s,i) (s->params[i].dvtype == GRETL_TYPE_DOUBLE)
71 
72 #define numeric_mode(s) (!(s->flags & NL_ANALYTICAL))
73 #define analytic_mode(s) (s->flags & NL_ANALYTICAL)
74 
75 #define scalar_loglik(s) (s->lhtype == GRETL_TYPE_DOUBLE)
76 #define suppress_grad_check(s) (s->opt & OPT_S)
77 
78 /* file-scope global variables */
79 
80 static nlspec private_spec;
81 
82 static char *adjust_saved_nlfunc (char *s);
83 
set_numeric_mode(nlspec * s)84 static void set_numeric_mode (nlspec *s)
85 {
86     s->flags &= ~NL_ANALYTICAL;
87 }
88 
set_analytic_mode(nlspec * s)89 static void set_analytic_mode (nlspec *s)
90 {
91     s->flags |= NL_ANALYTICAL;
92 }
93 
destroy_genrs_array(nlspec * s)94 static void destroy_genrs_array (nlspec *s)
95 {
96     int i;
97 
98     for (i=0; i<s->ngenrs; i++) {
99 	destroy_genr(s->genrs[i]);
100     }
101 
102     free(s->genrs);
103     s->genrs = NULL;
104     s->ngenrs = 0;
105 }
106 
check_lhs_vec(nlspec * s)107 static int check_lhs_vec (nlspec *s)
108 {
109     int v = gretl_vector_get_length(s->lvec);
110 
111     if (v != s->nobs) {
112 	fprintf(stderr, "LHS vector should be of length %d, is %d\n",
113 		s->nobs, v);
114 	return 1;
115     }
116 
117     return 0;
118 }
119 
get_derivative_matrix(nlspec * s,int i,int * err)120 static gretl_matrix *get_derivative_matrix (nlspec *s, int i, int *err)
121 {
122     gretl_matrix *m = genr_get_output_matrix(s->params[i].dgenr);
123 
124     if (m == NULL) {
125 	fprintf(stderr, "get_derivative_matrix: got NULL result\n");
126 	*err = E_DATA;
127     }
128 
129     return m;
130 }
131 
check_derivative_matrix(int i,gretl_matrix * m,nlspec * s)132 static int check_derivative_matrix (int i, gretl_matrix *m,
133 				    nlspec *s)
134 {
135     int r, c, v;
136 
137     if (m == NULL) {
138 	fprintf(stderr, "param %d, got NULL matrix derivative\n", i);
139 	return 1;
140     }
141 
142     r = gretl_matrix_rows(m);
143     c = gretl_matrix_cols(m);
144     v = s->params[i].nc;
145 
146     if (c != v || (r != 1 && r != s->nobs)) {
147 	fprintf(stderr, "matrix deriv for param %d is %d x %d: WRONG\n",
148 		i, r, c);
149 	fprintf(stderr, " should be %d x %d, or %d x %d\n", s->nobs,
150 		v, 1, v);
151 	return 1;
152     }
153 
154     return 0;
155 }
156 
nls_dynamic_check(nlspec * s,char * formula)157 static int nls_dynamic_check (nlspec *s, char *formula)
158 {
159     GENERATOR *genr;
160     double *y;
161     int T = s->dset->n;
162     int v = s->dv;
163     int err = 0;
164 
165     /* back up the dependent variable */
166     y = copyvec(s->dset->Z[v], T);
167     if (y == NULL) {
168 	return E_ALLOC;
169     }
170 
171     /* compile the formula for the dependent variable and see
172        if it is autoregressive */
173     strcpy(formula, s->nlfunc);
174     adjust_saved_nlfunc(formula);
175 
176     genr = genr_compile(formula, s->dset, GRETL_TYPE_SERIES,
177 			OPT_P | OPT_N, NULL, &err);
178 
179     if (!err && genr_is_autoregressive(genr)) {
180 	fprintf(stderr, "nls_dynamic_check: setting NL_AUTOREG\n");
181 	s->flags |= NL_AUTOREG;
182     }
183 
184     /* restore the dependent variable */
185     memcpy(s->dset->Z[v], y, T * sizeof *y);
186 
187     destroy_genr(genr);
188     free(y);
189 
190     return err;
191 }
192 
scalar_acceptable(nlspec * s,int i,const char * dername)193 static int scalar_acceptable (nlspec *s, int i, const char *dername)
194 {
195     if (i < s->naux) {
196 	/* an auxiliary variable: scalars OK */
197 	return 1;
198     } else if (i == s->naux) {
199 	/* the criterion value: accept a scalar for loglikelihood */
200 	return s->ci == MLE;
201     } else {
202 	/* i > s->naux: a derivative */
203 	return dername != NULL && gretl_is_scalar(dername);
204     }
205 }
206 
allocate_generators(nlspec * s)207 static int allocate_generators (nlspec *s)
208 {
209     int np = analytic_mode(s) ? s->nparam : 0;
210     int i, nlf = (s->nlfunc != NULL);
211     int err = 0;
212 
213     s->ngenrs = s->naux + nlf + np;
214     s->genrs = malloc(s->ngenrs * sizeof *s->genrs);
215 
216     if (s->genrs == NULL) {
217 	s->ngenrs = 0;
218 	err = E_ALLOC;
219     } else {
220 	for (i=0; i<s->ngenrs; i++) {
221 	    s->genrs[i] = NULL;
222 	}
223     }
224 
225     return err;
226 }
227 
unassigned_fncall(const char * s)228 static int unassigned_fncall (const char *s)
229 {
230     int n = gretl_namechar_spn(s);
231     int ret = 0;
232 
233     if (n > 0 && n < FN_NAMELEN && s[n] == '(') {
234 	char word[FN_NAMELEN];
235 
236 	*word = '\0';
237 	strncat(word, s, n);
238 	if (function_lookup(word) ||
239 	    get_user_function_by_name(word)) {
240 	    ret = 1;
241 	}
242     }
243 
244     return ret;
245 }
246 
genr_setup_error(const char * s,int err,int exec)247 static void genr_setup_error (const char *s, int err, int exec)
248 {
249     gchar *msg;
250 
251     if (exec) {
252 	msg = g_strdup_printf(_("The formula '%s'\n produced an error "
253 				"on execution"), s);
254     } else {
255 	msg = g_strdup_printf(_("The formula '%s'\n produced an error "
256 				"on compilation"), s);
257     }
258 
259     gretl_errmsg_append(msg, err);
260     g_free(msg);
261 }
262 
263 /* we "compile" the required equations first, so we can subsequently
264    execute the compiled versions for maximum efficiency
265 */
266 
nls_genr_setup(nlspec * s)267 static int nls_genr_setup (nlspec *s)
268 {
269     char formula[MAXLINE];
270     gretl_matrix *m;
271     int i, j, v;
272     int err = 0;
273 
274     err = allocate_generators(s);
275     if (err) {
276 	return err;
277     }
278 
279 #if NLS_DEBUG > 1
280     PRN *eprn = gretl_print_new(GRETL_PRINT_STDERR, NULL);
281 
282     if (eprn != NULL) {
283 	printdata(NULL, NULL, s->dset, OPT_O, eprn);
284 	gretl_print_destroy(eprn);
285     }
286 #endif
287 
288     /* We now loop across the "generators", setting them up
289        and checking them. We hook up any auxiliary genrs
290        first, then the criterion function, then the analytical
291        derivatives, if any.
292     */
293 
294     /* initialize the index for derivatives */
295     j = -1;
296 
297     for (i=0; i<s->ngenrs && !err; i++) {
298 	gretlopt genopt = OPT_P | OPT_N;
299 	GretlType gentype = GRETL_TYPE_ANY;
300 	GretlType result = 0;
301 	char *dname = NULL;
302 
303 	if (i < s->naux) {
304 	    /* auxiliary genrs */
305 	    strcpy(formula, s->aux[i]);
306 	    if (unassigned_fncall(formula)) {
307 		genopt |= OPT_O;
308 	    }
309 	} else if (i == s->naux) {
310 	    /* criterion function */
311 	    if (*s->lhname != '\0') {
312 		sprintf(formula, "%s = %s", s->lhname, s->nlfunc);
313 	    } else {
314 		if (s->ci == NLS && dataset_is_time_series(s->dset)) {
315 		    err = nls_dynamic_check(s, formula);
316 		}
317 		sprintf(formula, "$nl_y = %s", s->nlfunc);
318 	    }
319 	} else {
320 	    /* derivative */
321 	    sprintf(s->params[++j].dname, "$nl_x%d", i);
322 	    if (scalar_param(s, j)) {
323 		sprintf(formula, "%s = %s", s->params[j].dname,
324 			s->params[j].deriv);
325 	    } else {
326 		sprintf(formula, "%s = %s",  s->params[j].dname,
327 			s->params[j].deriv);
328 		gentype = GRETL_TYPE_MATRIX;
329 
330 	    }
331 	    dname = s->params[j].dname;
332 	}
333 
334 	if (!err) {
335 	    s->genrs[i] = genr_compile(formula, s->dset, gentype,
336 				       genopt, NULL, &err);
337 	}
338 
339 	if (err) {
340 	    fprintf(stderr, "nls: fail at genr_compile for genrs[%d]\n", i);
341 	    fprintf(stderr, "> '%s'\n", formula);
342 	    genr_setup_error(formula, err, 0);
343 	    break;
344 	}
345 
346 	/* see if the formula actually works, and flush out NAs
347 	   while we're at it
348 	*/
349 	genr_set_na_check(s->genrs[i]);
350 	err = execute_genr(s->genrs[i], s->dset, s->prn);
351 	genr_unset_na_check(s->genrs[i]);
352 
353 	if (err) {
354 	    genr_setup_error(formula, err, 1);
355 	    fprintf(stderr, "nls: fail at execute_genr for genrs[%d]\n", i);
356 	    fprintf(stderr, "> '%s'\n", formula);
357 	    break;
358 	}
359 
360 	/* skip ahead already? */
361 	if (genr_no_assign(s->genrs[i])) {
362 	    continue;
363 	}
364 
365 	v = 0;
366 	m = NULL;
367 
368 	/* modified 2016-04-03: limit the following test(s) to
369 	   the criterion function and derivatives
370 	*/
371 	if (i >= s->naux) {
372 	    v = genr_get_output_varnum(s->genrs[i]);
373 	    m = genr_get_output_matrix(s->genrs[i]);
374 	    if (v == 0 && m == NULL) {
375 		/* not a series, not a matrix: should be scalar */
376 		result = genr_get_output_type(s->genrs[i]);
377 		if (result != GRETL_TYPE_DOUBLE ||
378 		    !scalar_acceptable(s, i, dname)) {
379 		    gretl_errmsg_sprintf(_("The formula '%s'\n did not produce "
380 					   "the required output type"),
381 					 formula);
382 		    err = E_TYPES;
383 		    break;
384 		} else {
385 		    gentype = GRETL_TYPE_DOUBLE;
386 		}
387 	    }
388 	}
389 
390 	if (i == s->naux) {
391 	    /* the criterion function */
392 	    if (m != NULL) {
393 		s->lvec = m;
394 		s->lhtype = GRETL_TYPE_MATRIX;
395 		err = check_lhs_vec(s);
396 	    } else if (v > 0) {
397 		s->lhv = v;
398 		s->lhtype = GRETL_TYPE_SERIES;
399 	    } else if (gentype == GRETL_TYPE_DOUBLE) {
400 		s->lhtype = GRETL_TYPE_DOUBLE;
401 	    } else {
402 		err = E_TYPES;
403 	    }
404 	} else if (j >= 0) {
405 	    /* derivatives */
406 	    if (v > 0) {
407 		s->params[j].dvtype = GRETL_TYPE_SERIES;
408 	    } else if (m != NULL) {
409 		s->params[j].dvtype = GRETL_TYPE_MATRIX;
410 	    } else {
411 		s->params[j].dvtype = GRETL_TYPE_DOUBLE;
412 	    }
413 
414 	    s->params[j].dnum = v;
415 	    s->params[j].dgenr = s->genrs[i];
416 
417 	    if (m != NULL || !scalar_param(s, j)) {
418 		err = check_derivative_matrix(j, m, s);
419 	    }
420 	}
421 
422 #if NLS_DEBUG
423 	fprintf(stderr, " formula '%s'\n", formula);
424 	fprintf(stderr, " v = %d, m = %p\n", v, (void *) m);
425 	if (v > 0) {
426 	    fprintf(stderr, " second value: Z[%d][%d] = %g\n",
427 		    v, s->t1+1, s->dset->Z[v][s->t1+1]);
428 	}
429 #endif
430     }
431 
432     if (!err && s->hesscall != NULL) {
433 	s->hgen = genr_compile(s->hesscall, s->dset, GRETL_TYPE_ANY,
434 			       OPT_P | OPT_O, s->prn, &err);
435 	if (err) {
436 	    fprintf(stderr, "compilation of s->hgen failed\n");
437 	}
438     }
439 
440     if (err) {
441 	destroy_genrs_array(s);
442     }
443 
444     return err;
445 }
446 
447 /* If i == 0 we're calculating the function; if i > 0 we're calculating
448    a derivative.  Either way, we recalculate any auxiliary variables
449    first.
450 */
451 
nls_auto_genr(nlspec * s,int i)452 static int nls_auto_genr (nlspec *s, int i)
453 {
454     int j;
455 
456     s->generr = 0;
457 
458 #if NLS_DEBUG
459     fprintf(stderr, "nls_auto_genr: input i = %d\n", i);
460 #endif
461 
462     if (s->genrs == NULL) {
463 #if NLS_DEBUG
464 	fprintf(stderr, " calling nls_genr_setup\n");
465 #endif
466 	s->generr = nls_genr_setup(s);
467 	if (s->generr) {
468 	    fprintf(stderr, " nls_genr_setup failed\n");
469 	}
470 	return s->generr;
471     }
472 
473     for (j=0; j<s->naux; j++) {
474 #if NLS_DEBUG
475 	fprintf(stderr, " generating aux var %d (%p):\n %s\n",
476 		j, (void *) s->genrs[j], s->aux[j]);
477 #endif
478 	s->generr = execute_genr(s->genrs[j], s->dset, s->prn);
479 	if (s->generr) {
480 	    return s->generr;
481 	}
482     }
483 
484     if (i == 0 && s->nlfunc == NULL) {
485 	/* we're done */
486 	return s->generr;
487     }
488 
489     j = s->naux + i;
490 #if NLS_DEBUG
491     fprintf(stderr, " running genr %d (%p)\n", j, (void *) s->genrs[j]);
492 #endif
493     s->generr = execute_genr(s->genrs[j], s->dset, s->prn);
494 #if NLS_DEBUG
495     fprintf(stderr, "  err = %d\n", s->generr);
496 #endif
497 
498     /* make sure we have a correct pointer to matrix deriv */
499     if (!s->generr && i > 0 && matrix_deriv(s, i-1)) {
500 	gretl_matrix *m = genr_get_output_matrix(s->genrs[j]);
501 
502 	s->generr = check_derivative_matrix(i-1, m, s);
503     }
504 
505 #if NLS_DEBUG
506     if (s->generr) {
507 	int v = genr_get_output_varnum(s->genrs[j]);
508 
509 	fprintf(stderr, " varnum = %d, err = %d\n", v, s->generr);
510 	errmsg(s->generr, s->prn);
511     }
512 #endif
513 
514     return s->generr;
515 }
516 
517 /* wrappers for the above to enhance comprehensibility below */
518 
nl_calculate_fvec(nlspec * s)519 int nl_calculate_fvec (nlspec *s)
520 {
521     return nls_auto_genr(s, 0);
522 }
523 
nls_calculate_deriv(nlspec * s,int i)524 static int nls_calculate_deriv (nlspec *s, int i)
525 {
526     return nls_auto_genr(s, i + 1);
527 }
528 
529 /* end wrappers */
530 
nlspec_destroy_arrays(nlspec * s)531 void nlspec_destroy_arrays (nlspec *s)
532 {
533     free(s->params);
534     s->params = NULL;
535     s->nparam = 0;
536 
537     free(s->coeff);
538     s->coeff = NULL;
539     s->ncoeff = 0;
540 }
541 
542 /* add a vector of coefficients to the model specification */
543 
push_vec_coeffs(nlspec * s,gretl_matrix * m,int k)544 static int push_vec_coeffs (nlspec *s, gretl_matrix *m, int k)
545 {
546     double *coeff;
547     int i, nc = s->ncoeff;
548 
549     if (k == 0) {
550 	return E_DATA;
551     }
552 
553     coeff = realloc(s->coeff, (nc + k) * sizeof *coeff);
554     if (coeff == NULL) {
555 	return E_ALLOC;
556     }
557 
558     for (i=0; i<k; i++) {
559 	coeff[nc + i] = m->val[i];
560     }
561 
562 #if NLS_DEBUG
563     fprintf(stderr, "added %d coeffs\n", k);
564 #endif
565 
566     s->coeff = coeff;
567     s->ncoeff = nc + k;
568 
569     return 0;
570 }
571 
572 /* add a scalar coefficient to the model specification */
573 
push_scalar_coeff(nlspec * s,double x)574 static int push_scalar_coeff (nlspec *s, double x)
575 {
576     double *coeff;
577     int nc = s->ncoeff;
578 
579     coeff = realloc(s->coeff, (nc + 1) * sizeof *coeff);
580     if (coeff == NULL) {
581 	return E_ALLOC;
582     }
583 
584     coeff[nc] = x;
585 
586 #if NLS_DEBUG
587     fprintf(stderr, "added coeff[%d] = %g\n", nc, x);
588 #endif
589 
590     s->coeff = coeff;
591     s->ncoeff = nc + 1;
592 
593     return 0;
594 }
595 
get_param_scalar(parm * p)596 static double get_param_scalar (parm *p)
597 {
598     double x = NADBL;
599 
600     if (p->bundle != NULL) {
601 	int err = 0;
602 
603 	x = gretl_bundle_get_scalar(p->bundle, p->name, &err);
604     } else {
605 	x = gretl_scalar_get_value(p->name, NULL);
606     }
607 
608     return x;
609 }
610 
get_param_vector(parm * p)611 static gretl_matrix *get_param_vector (parm *p)
612 {
613     gretl_matrix *m = NULL;
614 
615     if (p->bundle != NULL) {
616 	int err = 0;
617 
618 	m = gretl_bundle_get_matrix(p->bundle, p->name, &err);
619     } else {
620 	m = get_matrix_by_name(p->name);
621     }
622 
623     return m;
624 }
625 
626 /* add a parameter to the model specification: this may be
627    either a scalar or a vector
628 */
629 
nlspec_push_param(nlspec * s,const char * name,GretlType type,gretl_bundle * bundle,char * deriv)630 static int nlspec_push_param (nlspec *s,
631 			      const char *name,
632 			      GretlType type,
633 			      gretl_bundle *bundle,
634 			      char *deriv)
635 {
636     parm *params, *p;
637     int np = s->nparam;
638     int err;
639 
640     params = realloc(s->params, (np + 1) * sizeof *params);
641     if (params == NULL) {
642 	return E_ALLOC;
643     }
644 
645     p = &params[np];
646 
647     p->name[0] = '\0';
648     strncat(p->name, name, VNAMELEN - 1);
649     p->type = type;
650     p->bundle = bundle;
651     p->dvtype = GRETL_TYPE_NONE;
652     p->deriv = deriv;
653     p->dnum = 0;
654     p->nc = 1;
655     p->dname[0] = '\0';
656     p->dgenr = NULL;
657     p->vec = NULL;
658 
659 #if NLS_DEBUG
660     fprintf(stderr, "added param[%d] = '%s'\n", np, p->name);
661 #endif
662 
663     s->params = params;
664     s->nparam = np + 1;
665 
666     if (type == GRETL_TYPE_DOUBLE) {
667 	double x = get_param_scalar(p);
668 
669 	err = push_scalar_coeff(s, x);
670     } else {
671 	gretl_matrix *m = get_param_vector(p);
672 	int k = gretl_vector_get_length(m);
673 
674 #if NLS_DEBUG
675 	fprintf(stderr, "vector param: m = %p, k = %d\n", (void *) m, k);
676 #endif
677 	p->vec = m;
678 	p->nc = k;
679 	err = push_vec_coeffs(s, m, k);
680 	if (!err) {
681 	    s->nvec += 1;
682 	}
683     }
684 
685     return err;
686 }
687 
check_matrix_param(const char * name,gretl_bundle * b)688 static int check_matrix_param (const char *name, gretl_bundle *b)
689 {
690     gretl_matrix *m;
691     int err = 0;
692 
693     if (b == NULL) {
694 	m = get_matrix_by_name(name);
695     } else {
696 	m = gretl_bundle_get_matrix(b, name, &err);
697     }
698 
699     if (err || m == NULL || gretl_vector_get_length(m) == 0) {
700 	gretl_errmsg_sprintf(_("'%s': expected a scalar or vector"), name);
701 	err = E_TYPES;
702     }
703 
704     return err;
705 }
706 
707 /* Do we have a valid name (the name of a scalar or vector?):
708    if so return 0, else return E_TYPES.
709 */
710 
check_param_name(char ** pname,GretlType * type,gretl_bundle ** pbundle)711 static int check_param_name (char **pname, GretlType *type,
712 			     gretl_bundle **pbundle)
713 {
714     gretl_bundle *b = NULL;
715     char *name = *pname;
716     int err = 0;
717 
718     if (pbundle != NULL && strchr(name, '.') != NULL) {
719 	/* did we get a bundle member? */
720 	gchar **S = g_strsplit(name, ".", 2);
721 
722 	b = get_bundle_by_name(S[0]);
723 
724 	if (b != NULL) {
725 	    GretlType btype;
726 	    int berr = 0;
727 
728 	    btype = gretl_bundle_get_member_type(b, S[1], &berr);
729 	    if (btype == GRETL_TYPE_DOUBLE) {
730 		*type = GRETL_TYPE_DOUBLE;
731 	    } else if (btype == GRETL_TYPE_MATRIX) {
732 		err = check_matrix_param(S[1], b);
733 		if (!err) {
734 		    *type = GRETL_TYPE_MATRIX;
735 		}
736 	    } else {
737 		err = E_TYPES;
738 	    }
739 	    if (!err) {
740 		free(*pname);
741 		*pname = gretl_strdup(S[1]);
742 		*pbundle = b;
743 	    }
744 	} else {
745 	    err = E_TYPES;
746 	}
747 	g_strfreev(S);
748     } else if (gretl_is_scalar(name)) {
749 	*type = GRETL_TYPE_DOUBLE;
750     } else {
751 	err = check_matrix_param(name, NULL);
752 	if (!err) {
753 	    *type = GRETL_TYPE_MATRIX;
754 	}
755     }
756 
757     return err;
758 }
759 
nlspec_add_param_names(nlspec * spec,const char * s)760 static int nlspec_add_param_names (nlspec *spec, const char *s)
761 {
762     const char *test = NULL;
763     int n, err = 0;
764 
765     s += strspn(s, " ");
766 
767     if (*s == '"') {
768 	/* inline string literal */
769 	const char *p = strchr(s+1, '"');
770 
771 	if (p == NULL) {
772 	    err = E_INVARG;
773 	} else {
774 	    n = p - s - 1;
775 	    if (n > 0) {
776 		spec->parnames = gretl_strndup(s+1, n);
777 	    } else {
778 		err = E_INVARG;
779 	    }
780 	    test = p + 1;
781 	}
782     } else {
783 	/* name of string variable? */
784 	char sname[VNAMELEN];
785 
786 	n = gretl_namechar_spn(s);
787 
788 	if (n == 0 || n >= VNAMELEN) {
789 	    err = E_INVARG;
790 	} else {
791 	    user_var *uv = NULL;
792 
793 	    test = s + n;
794 	    *sname = '\0';
795 	    strncat(sname, s, n);
796 	    uv = get_user_var_by_name(sname);
797 	    if (uv == NULL) {
798 		err = E_INVARG;
799 	    } else if (user_var_get_type(uv) == GRETL_TYPE_STRING) {
800 		/* got a composite string variable */
801 		const char *names = get_string_by_name(sname);
802 
803 		if (names == NULL || *names == '\0') {
804 		    err = E_INVARG;
805 		} else {
806 		    free(spec->parnames);
807 		    spec->parnames = gretl_strdup(names);
808 		    if (spec->parnames == NULL) {
809 			err = E_ALLOC;
810 		    }
811 		}
812 	    } else if (user_var_get_type(uv) == GRETL_TYPE_ARRAY) {
813 		/* got an array of strings */
814 		gretl_array *a = user_var_get_value(uv);
815 
816 		if (gretl_array_get_type(a) == GRETL_TYPE_STRINGS) {
817 		    spec->parnames = gretl_strdup(sname);
818 		    spec->flags |= NL_NAMES_ARRAY;
819 		} else {
820 		    err = E_INVARG;
821 		}
822 	    } else {
823 		err = E_INVARG;
824 	    }
825 	}
826     }
827 
828     if (!err && test != NULL && !string_is_blank(test)) {
829 	gretl_errmsg_set("found trailing junk on command line\n");
830 	err = E_INVARG;
831     }
832 
833     return err;
834 }
835 
836 /* For case where analytical derivatives are not given, the user
837    must supply a line like:
838 
839    params b0 b1 b2 b3
840 
841    specifying the parameters to be estimated.  Here we parse such a
842    list and add the parameter info to the spec.  The terms in the list
843    must be pre-existing scalars or vectors, either objects in their
844    own right or members of a bundle.
845 */
846 
847 static int
nlspec_add_params_from_line(nlspec * s,const char * str)848 nlspec_add_params_from_line (nlspec *s, const char *str)
849 {
850     int i, nf = count_fields(str, NULL);
851     int err = 0;
852 
853     if (s->params != NULL) {
854 	gretl_errmsg_set(_("Only one 'params' specification is allowed"));
855 	return E_DATA;
856     } else if (nf == 0) {
857 	return E_PARSE;
858     }
859 
860 #if NLS_DEBUG
861     fprintf(stderr, "nlspec_add_params_from_line:\n "
862 	    "line = '%s', nf = %d\n", str, nf);
863 #endif
864 
865     for (i=0; i<nf && !err; i++) {
866 	gretlopt opt = OPT_S | OPT_D | OPT_U;
867 	char *name = gretl_word_strdup(str, &str, opt, &err);
868 	gretl_bundle *bundle = NULL;
869 	GretlType type = 0;
870 
871 	if (!err) {
872 	    err = check_param_name(&name, &type, &bundle);
873 	}
874 
875 	if (!err) {
876 	    err = nlspec_push_param(s, name, type,
877 				    bundle, NULL);
878 	}
879 
880 	free(name);
881     }
882 
883     if (err) {
884 	nlspec_destroy_arrays(s);
885     }
886 
887     return err;
888 }
889 
nlspec_add_scalar_params(nlspec * spec,int np,double * vals,char ** names,gretlopt opt)890 static int nlspec_add_scalar_params (nlspec *spec, int np,
891 				     double *vals, char **names,
892 				     gretlopt opt)
893 {
894     int i, err = 0;
895 
896     if (spec->params != NULL || np == 0) {
897 	return E_DATA;
898     }
899 
900     for (i=0; i<np && !err; i++) {
901 	if (opt & OPT_A) {
902 	    /* doing internal auxiliary NLS (e.g. arma init) */
903 	    err = add_auxiliary_scalar(names[i], vals[i]);
904 	} else {
905 	    err = gretl_scalar_add(names[i], vals[i]);
906 	}
907 	if (!err) {
908 	    err = nlspec_push_param(spec, names[i], GRETL_TYPE_DOUBLE,
909 				    NULL, NULL);
910 	}
911     }
912 
913     if (err) {
914 	nlspec_destroy_arrays(spec);
915     }
916 
917     return err;
918 }
919 
920 /**
921  * nlspec_add_param_list:
922  * @spec: nls specification.
923  * @np: number of parameters.
924  * @vals: array of initial parameter values.
925  * @names: array of parameter names.
926  *
927  * Adds to @spec a list of (scalar) parameters to be estimated.
928  * For an example of use see nls_example.c in the gretl extra
929  * subdirectory.
930  *
931  * Returns: 0 on success, non-zero error code on error.
932  */
933 
nlspec_add_param_list(nlspec * spec,int np,double * vals,char ** names)934 int nlspec_add_param_list (nlspec *spec, int np, double *vals,
935 			   char **names)
936 {
937     return nlspec_add_scalar_params(spec, np, vals, names,
938 				    OPT_NONE);
939 
940 }
941 
aux_nlspec_add_param_list(nlspec * spec,int np,double * vals,char ** names)942 int aux_nlspec_add_param_list (nlspec *spec, int np, double *vals,
943 			       char **names)
944 {
945     return nlspec_add_scalar_params(spec, np, vals, names,
946 				    OPT_A);
947 }
948 
949 /* update the 'external' values of scalars or vectors using
950    the values produced by the optimizer.
951 */
952 
update_coeff_values(const double * b,nlspec * s)953 int update_coeff_values (const double *b, nlspec *s)
954 {
955     int i, j, k = 0;
956     int err = 0;
957 
958     for (i=0; i<s->nparam; i++) {
959 	parm *p = &s->params[i];
960 
961 	if (scalar_param(s, i)) {
962 	    if (p->bundle != NULL) {
963 		err = gretl_bundle_set_scalar(p->bundle, p->name, b[k++]);
964 	    } else {
965 		err = gretl_scalar_set_value(p->name, b[k++]);
966 	    }
967 	} else {
968 	    gretl_matrix *m = get_param_vector(p);
969 
970 	    if (m == NULL) {
971 		fprintf(stderr, "Couldn't find location for coeff %d\n", k);
972 		err = E_DATA;
973 	    } else {
974 		if (m != p->vec) {
975 		    fprintf(stderr, "*** coeff_address: by name, '%s' is at %p; "
976 			    "stored addr = %p\n", p->name,
977 			    (void *) m, (void *) p->vec);
978 		    p->vec = m;
979 		}
980 		for (j=0; j<p->nc; j++) {
981 		    gretl_vector_set(m, j, b[k++]);
982 		}
983 	    }
984 	}
985     }
986 
987     return err;
988 }
989 
nl_coeff_check(nlspec * s)990 static int nl_coeff_check (nlspec *s)
991 {
992     int i;
993 
994     for (i=0; i<s->ncoeff; i++) {
995 	if (na(s->coeff[i])) {
996 	    gretl_errmsg_set("Unitialized parameter");
997 	    return E_DATA;
998 	}
999     }
1000 
1001     return 0;
1002 }
1003 
1004 /* Adjust starting and ending points of sample if need be, to avoid
1005    missing values; abort if there are missing values within the
1006    (possibly reduced) sample range.  For this purpose we generate the
1007    nls residual, or the loglikelihood in case of MLE.
1008 */
1009 
nl_missval_check(nlspec * s,const DATASET * dset)1010 static int nl_missval_check (nlspec *s, const DATASET *dset)
1011 {
1012     int t1 = s->t1, t2 = s->t2;
1013     int t, v;
1014     int err = 0;
1015 
1016 #if NLS_DEBUG
1017     fprintf(stderr, "nl_missval_check: calling nl_calculate_fvec\n");
1018 #endif
1019 
1020     /* calculate the function (NLS residual, MLE likelihood) */
1021     err = nl_calculate_fvec(s);
1022     if (err) {
1023 	return err;
1024     }
1025 
1026     if (s->lvec != NULL || s->lhtype == GRETL_TYPE_DOUBLE) {
1027 	/* the calculation gives a matrix or scalar */
1028 	goto nl_miss_exit;
1029     }
1030 
1031     /* ID number of LHS variable */
1032     v = s->lhv;
1033 
1034 #if NLS_DEBUG
1035     fprintf(stderr, " checking var %d (%s)\n",
1036 	    v, s->dset->varname[v]);
1037     fprintf(stderr, "  before trimming: spec->t1 = %d, spec->t2 = %d\n",
1038 	    s->t1, s->t2);
1039 #endif
1040 
1041     for (t1=s->t1; t1<=s->t2; t1++) {
1042 	if (!na(s->dset->Z[v][t1])) {
1043 	    break;
1044 	}
1045     }
1046 
1047     for (t2=s->t2; t2>=t1; t2--) {
1048 	if (!na(s->dset->Z[v][t2])) {
1049 	    break;
1050 	}
1051     }
1052 
1053     if (t2 - t1 + 1 == 0) {
1054 	fprintf(stderr, "nl_missval_check: no valid data\n");
1055 	return E_DATA;
1056     }
1057 
1058     if (t2 - t1 + 1 < s->ncoeff) {
1059 	return E_DF;
1060     }
1061 
1062     for (t=t1; t<=t2; t++) {
1063 	if (na(s->dset->Z[v][t])) {
1064 	    fprintf(stderr, "  after setting t1=%d, t2=%d, "
1065 		    "got NA for var %d (%s) at obs %d\n", t1, t2, v,
1066 		    dset->varname[v], t);
1067 	    return E_MISSDATA;
1068 	}
1069     }
1070 
1071  nl_miss_exit:
1072 
1073     s->t1 = s->real_t1 = t1;
1074     s->t2 = s->real_t2 = t2;
1075     s->nobs = t2 - t1 + 1;
1076 
1077 #if NLS_DEBUG
1078     fprintf(stderr, "  after: spec->t1 = %d, spec->t2 = %d, spec->nobs = %d\n\n",
1079 	    s->t1, s->t2, s->nobs);
1080 #endif
1081 
1082     return err;
1083 }
1084 
1085 /* get_mle_ll: callback used by BFGS.  Note that this should return
1086    NADBL in case of numerical problems; that signals to BFGS to
1087    try a smaller step length.
1088 */
1089 
get_mle_ll(const double * b,void * p)1090 static double get_mle_ll (const double *b, void *p)
1091 {
1092     nlspec *s = (nlspec *) p;
1093     double x;
1094     int t, k, err;
1095 
1096     update_coeff_values(b, s);
1097 
1098     err = nl_calculate_fvec(s);
1099     if (err) {
1100 	return NADBL;
1101     }
1102 
1103     if (s->lhtype == GRETL_TYPE_DOUBLE) {
1104 	s->crit = gretl_scalar_get_value(s->lhname, NULL);
1105 	return s->crit;
1106     }
1107 
1108     s->crit = 0.0;
1109 
1110     if (s->lhtype == GRETL_TYPE_MATRIX) {
1111 	s->lvec = get_matrix_by_name(s->lhname);
1112 	if (s->lvec == NULL) {
1113 	    fprintf(stderr, "get_mle_ll: s->lvec is gone!\n");
1114 	    return NADBL;
1115 	}
1116     }
1117 
1118     if (s->lvec != NULL) {
1119 	k = gretl_vector_get_length(s->lvec);
1120 	for (t=0; t<k; t++) {
1121 	    x = s->lvec->val[t];
1122 	    if (na(x)) {
1123 		s->crit = NADBL;
1124 		break;
1125 	    }
1126 	    s->crit += x;
1127 	}
1128     } else {
1129 	k = s->lhv;
1130 	for (t=s->t1; t<=s->t2; t++) {
1131 	    x = s->dset->Z[k][t];
1132 	    if (na(x)) {
1133 		s->crit = NADBL;
1134 		break;
1135 	    }
1136 	    s->crit += x;
1137 	}
1138     }
1139 
1140 #if 0
1141     fprintf(stderr, "get_mle_ll: crit=%g\n", s->crit);
1142 #endif
1143 
1144     return s->crit;
1145 }
1146 
1147 /* this function is used in the context of the minpack callback, and
1148    also for checking derivatives in the MLE case
1149 */
1150 
nl_function_calc(double * f,double * x,void * p)1151 static int nl_function_calc (double *f, double *x, void *p)
1152 {
1153     nlspec *s = (nlspec *) p;
1154     const double *y;
1155     int t, err = 0;
1156 
1157 #if NLS_DEBUG > 1
1158     fprintf(stderr, "\n*** nl_function_calc called\n");
1159 #endif
1160 
1161     /* calculate function given current parameter estimates */
1162     err = nl_calculate_fvec(s);
1163     if (err) {
1164 	return err;
1165     }
1166 
1167     s->crit = 0.0;
1168 
1169     if (s->lvec != NULL) {
1170 	y = s->lvec->val;
1171     } else {
1172 	y = s->dset->Z[s->lhv] + s->t1;
1173     }
1174 
1175     /* transcribe from vector or series to array @f */
1176     for (t=0; t<s->nobs; t++) {
1177 	if (na(y[t])) {
1178 	    fprintf(stderr, "nl_calculate_fvec: produced NA at obs %d\n", t+1);
1179 	    return 1;
1180 	}
1181 	f[t] = y[t];
1182 #if NLS_DEBUG > 1
1183 	fprintf(stderr, "fvec[%d] = %.14g\n", t,  f[t]);
1184 #endif
1185 	if (s->ci == MLE) {
1186 	    s->crit += f[t];
1187 	} else {
1188 	    /* sum of squares */
1189 	    s->crit += f[t] * f[t];
1190 	}
1191     }
1192 
1193     s->iters += 1;
1194 
1195     if (s->ci == NLS && (s->opt & OPT_V)) {
1196 	/* nls verbose output */
1197 	print_iter_info(s->iters, s->crit, C_SSR, s->ncoeff,
1198 			x, NULL, 0, s->prn);
1199     }
1200 
1201     return 0;
1202 }
1203 
get_nls_derivs(int T,double * g,DATASET * gdset,void * p)1204 static int get_nls_derivs (int T, double *g, DATASET *gdset, void *p)
1205 {
1206     nlspec *spec = (nlspec *) p;
1207     double *gi;
1208     double x;
1209     int j, t, k;
1210     int err = 0;
1211 
1212     if (g != NULL) {
1213 	/* coming from nls_calc, writing to flat array */
1214 	gi = g;
1215     } else if (gdset != NULL) {
1216 	/* coming from GNR, writing to a dataset */
1217 	gi = gdset->Z[2];
1218     } else {
1219 	return 1;
1220     }
1221 
1222     k = 0;
1223 
1224     for (j=0; j<spec->nparam && !err; j++) {
1225 	if (nls_calculate_deriv(spec, j)) {
1226 	    return 1;
1227 	}
1228 	if (matrix_deriv(spec, j)) {
1229 	    gretl_matrix *m = get_derivative_matrix(spec, j, &err);
1230 	    int i;
1231 
1232 	    for (i=0; i<m->cols && !err; i++) {
1233 		x = gretl_matrix_get(m, 0, i);
1234 		for (t=0; t<T; t++) {
1235 		    if (t > 0 && t < m->rows) {
1236 			x = gretl_matrix_get(m, t, i);
1237 		    }
1238 		    gi[t] = (spec->ci == MLE)? x : -x;
1239 		}
1240 		if (++k == spec->ncoeff) {
1241 		    break;
1242 		} if (g != NULL) {
1243 		    gi += T;
1244 		} else {
1245 		    gi = gdset->Z[k+2];
1246 		}
1247 	    }
1248 	} else if (scalar_deriv(spec, j)) {
1249 	    x = gretl_scalar_get_value(spec->params[j].dname, NULL);
1250 	    for (t=0; t<T; t++) {
1251 		gi[t] = (spec->ci == MLE)? x : -x;
1252 	    }
1253 	    if (++k == spec->ncoeff) {
1254 		break;
1255 	    } else if (g != NULL) {
1256 		gi += T;
1257 	    } else {
1258 		gi = gdset->Z[k+2];
1259 	    }
1260 	} else {
1261 	    /* derivative is series */
1262 	    int s, v = spec->params[j].dnum;
1263 
1264 	    if (v == 0) {
1265 		/* FIXME? */
1266 		v = spec->params[j].dnum = spec->dset->v - 1;
1267 	    }
1268 
1269 	    /* transcribe from dataset to array g */
1270 	    for (t=0; t<T; t++) {
1271 		s = t + spec->t1;
1272 		x = spec->dset->Z[v][s];
1273 		gi[t] = (spec->ci == MLE)? x : -x;
1274 	    }
1275 	    if (++k == spec->ncoeff) {
1276 		break;
1277 	    } else if (g != NULL) {
1278 		gi += T;
1279 	    } else {
1280 		gi = gdset->Z[k+2];
1281 	    }
1282 	}
1283     }
1284 
1285     return err;
1286 }
1287 
1288 /* for use with analytical derivatives, at present only for mle */
1289 
get_mle_gradient(double * b,double * g,int n,BFGS_CRIT_FUNC llfunc,void * p)1290 static int get_mle_gradient (double *b, double *g, int n,
1291 			     BFGS_CRIT_FUNC llfunc,
1292 			     void *p)
1293 {
1294     nlspec *spec = (nlspec *) p;
1295     gretl_matrix *m;
1296     double x;
1297     int i, j, k, t;
1298     int err = 0;
1299 
1300     update_coeff_values(b, spec);
1301 
1302     i = 0;
1303 
1304     for (j=0; j<spec->nparam && !err; j++) {
1305 	if (nls_calculate_deriv(spec, j)) {
1306 	    return 1;
1307 	}
1308 	if (matrix_deriv(spec, j)) {
1309 	    m = get_derivative_matrix(spec, j, &err);
1310 	    for (k=0; k<m->cols && !err; k++) {
1311 		g[i] = 0.0;
1312 		for (t=0; t<m->rows; t++) {
1313 		    x = gretl_matrix_get(m, t, k);
1314 		    if (na(x)) {
1315 			fprintf(stderr, "NA in gradient calculation\n");
1316 			err = 1;
1317 		    } else {
1318 			g[i] += x;
1319 		    }
1320 		}
1321 		i++;
1322 	    }
1323 	} else if (scalar_deriv(spec, j)) {
1324 	    x = gretl_scalar_get_value(spec->params[j].dname, NULL);
1325 	    if (na(x)) {
1326 		fprintf(stderr, "NA in gradient calculation\n");
1327 		err = 1;
1328 	    } else {
1329 		g[i++] = x;
1330 	    }
1331 	} else {
1332 	    /* the derivative must be a series */
1333 	    int v = spec->params[j].dnum;
1334 
1335 	    g[i] = 0.0;
1336 	    for (t=spec->t1; t<=spec->t2; t++) {
1337 		x = spec->dset->Z[v][t];
1338 		if (na(x)) {
1339 		    fprintf(stderr, "NA in gradient calculation\n");
1340 		    err = 1;
1341 		} else {
1342 		    g[i] += x;
1343 		}
1344 	    }
1345 	    i++;
1346 	}
1347     }
1348 
1349     return err;
1350 }
1351 
get_mle_hessian(double * b,gretl_matrix * H,void * p)1352 static int get_mle_hessian (double *b, gretl_matrix *H, void *p)
1353 {
1354     nlspec *spec = (nlspec *) p;
1355     int k = H->rows;
1356     int err;
1357 
1358     if (b != NULL) {
1359 	update_coeff_values(b, spec);
1360     }
1361 
1362     err = execute_genr(spec->hgen, spec->dset, spec->prn);
1363 
1364     if (!err) {
1365 	gretl_matrix *uH = get_matrix_by_name(spec->hname);
1366 
1367 	if (uH == NULL) {
1368 	    err = E_UNKVAR;
1369 	} else if (uH->rows != k || uH->cols != k) {
1370 	    err = E_NONCONF;
1371 	} else {
1372 	    gretl_matrix_copy_values(H, uH);
1373 	}
1374     }
1375 
1376     return err;
1377 }
1378 
mle_hessian_inverse(nlspec * spec,int * err)1379 static gretl_matrix *mle_hessian_inverse (nlspec *spec, int *err)
1380 {
1381     int k = spec->ncoeff;
1382     gretl_matrix *H = gretl_matrix_alloc(k, k);
1383 
1384     if (H == NULL) {
1385 	*err = E_ALLOC;
1386     } else {
1387 	*err = get_mle_hessian(NULL, H, spec);
1388     }
1389 
1390     if (!*err) {
1391 	*err = gretl_invert_symmetric_matrix(H);
1392 	if (*err) {
1393 	    fprintf(stderr, "mle_hessian_inverse: failed\n");
1394 	    gretl_matrix_free(H);
1395 	    H = NULL;
1396 	}
1397     }
1398 
1399     return H;
1400 }
1401 
1402 /* Compute auxiliary statistics and add them to the NLS
1403    model struct */
1404 
add_stats_to_model(MODEL * pmod,nlspec * spec)1405 static void add_stats_to_model (MODEL *pmod, nlspec *spec)
1406 {
1407     int dv = spec->dv;
1408     double d, tss;
1409     int s, t;
1410 
1411     pmod->ess = spec->crit;
1412     pmod->sigma = sqrt(pmod->ess / (pmod->nobs - spec->ncoeff));
1413 
1414     pmod->ybar = gretl_mean(pmod->t1, pmod->t2, spec->dset->Z[dv]);
1415     pmod->sdy = gretl_stddev(pmod->t1, pmod->t2, spec->dset->Z[dv]);
1416 
1417     s = (spec->missmask != NULL)? 0 : pmod->t1;
1418 
1419     tss = 0.0;
1420     for (t=pmod->t1; t<=pmod->t2; t++) {
1421 	d = spec->dset->Z[dv][s++] - pmod->ybar;
1422 	tss += d * d;
1423     }
1424 
1425     /* before over-writing the Gauss-Newton R^2, record it:
1426        it should be very small at convergence
1427     */
1428     gretl_model_set_double(pmod, "GNR_Rsquared", pmod->rsq);
1429 
1430     if (tss == 0.0) {
1431 	pmod->rsq = pmod->adjrsq = NADBL;
1432     } else {
1433 	pmod->rsq = 1.0 - pmod->ess / tss;
1434 	pmod->adjrsq = 1.0 - (1.0 - pmod->rsq) *
1435 	    ((double) (pmod->nobs - 1) / (pmod->nobs - pmod->ncoeff));
1436     }
1437 }
1438 
1439 /* returns the per-observation contributions to the log
1440    likelihood */
1441 
mle_llt_callback(const double * b,int i,void * p)1442 static const double *mle_llt_callback (const double *b, int i, void *p)
1443 {
1444     nlspec *s = (nlspec *) p;
1445     int err;
1446 
1447     update_coeff_values(b, s);
1448     err = nl_calculate_fvec(s);
1449 
1450     if (err) {
1451 	return NULL;
1452     } else if (s->lhtype == GRETL_TYPE_MATRIX) {
1453 	s->lvec = get_matrix_by_name(s->lhname);
1454 	if (s->lvec == NULL) {
1455 	    fprintf(stderr, "mle_llt_callback: s->lvec is gone!\n");
1456 	    return NULL;
1457 	} else {
1458 	    return s->lvec->val;
1459 	}
1460     } else {
1461 	return s->dset->Z[s->lhv] + s->t1;
1462     }
1463 }
1464 
ml_gradient_matrix(nlspec * spec,int * err)1465 static gretl_matrix *ml_gradient_matrix (nlspec *spec, int *err)
1466 {
1467     gretl_matrix *G = NULL;
1468     int k = spec->ncoeff;
1469     int T = spec->nobs;
1470 
1471     if (numeric_mode(spec)) {
1472 	G = numerical_score_matrix(spec->coeff, T, k, mle_llt_callback,
1473 				   (void *) spec, err);
1474     } else {
1475 	/* using analytical derivatives */
1476 	gretl_matrix *m;
1477 	double x = 0.0;
1478 	int i, j, v, s, t;
1479 
1480 	if (spec->nparam == 1 && matrix_deriv(spec, 0)) {
1481 	    m = get_derivative_matrix(spec, 0, err);
1482 	    if (!*err) {
1483 		G = gretl_matrix_copy(m);
1484 		if (G == NULL) {
1485 		    *err = E_ALLOC;
1486 		}
1487 	    }
1488 	    return G;
1489 	}
1490 
1491 	G = gretl_matrix_alloc(T, k);
1492 	if (G == NULL) {
1493 	    *err = E_ALLOC;
1494 	    return NULL;
1495 	}
1496 	j = 0;
1497 	for (i=0; i<spec->nparam; i++) {
1498 	    if (matrix_deriv(spec, i)) {
1499 		m = get_derivative_matrix(spec, i, err);
1500 		if (*err != 0) {
1501 		    break;
1502 		}
1503 		for (s=0; s<m->cols; s++) {
1504 		    x = gretl_matrix_get(m, 0, s);
1505 		    for (t=0; t<T; t++) {
1506 			if (t > 0 && t < m->rows) {
1507 			    x = gretl_matrix_get(m, t, s);
1508 			}
1509 			gretl_matrix_set(G, t, j, x);
1510 		    }
1511 		    j++;
1512 		}
1513 	    } else if (scalar_deriv(spec, i)) {
1514 		x = gretl_scalar_get_value(spec->params[i].dname, NULL);
1515 		for (t=0; t<T; t++) {
1516 		    gretl_matrix_set(G, t, j, x);
1517 		}
1518 		j++;
1519 	    } else {
1520 		v = spec->params[i].dnum;
1521 		for (t=0; t<T; t++) {
1522 		    x = spec->dset->Z[v][t + spec->t1];
1523 		    gretl_matrix_set(G, t, j, x);
1524 		}
1525 		j++;
1526 	    }
1527 	}
1528     }
1529 
1530     return G;
1531 }
1532 
ml_robust_specifier(nlspec * spec)1533 static gretlopt ml_robust_specifier (nlspec *spec)
1534 {
1535     if (spec->opt & OPT_C) {
1536 	/* clustered */
1537 	return OPT_C;
1538     } else {
1539 	const char *s = get_optval_string(MLE, OPT_R);
1540 
1541 	if (s != NULL && !strcmp(s, "hac")) {
1542 	    return OPT_N; /* Newey-West */
1543 	}
1544     }
1545 
1546     return OPT_NONE;
1547 }
1548 
mle_add_vcv(MODEL * pmod,nlspec * spec)1549 static int mle_add_vcv (MODEL *pmod, nlspec *spec)
1550 {
1551     int err = 0;
1552 
1553     if (spec->opt & OPT_A) {
1554 	/* auxiliary model: no VCV */
1555 	int i;
1556 
1557 	for (i=0; i<pmod->ncoeff; i++) {
1558 	    pmod->sderr[i] = NADBL;
1559 	}
1560     } else if (spec->opt & OPT_H) {
1561 	err = gretl_model_add_hessian_vcv(pmod, spec->Hinv);
1562     } else {
1563 	gretl_matrix *G = ml_gradient_matrix(spec, &err);
1564 
1565 	if (!err) {
1566 	    if ((spec->opt & (OPT_R | OPT_C)) && spec->Hinv != NULL) {
1567 		/* robust option: QML, possibly clustered or HAC */
1568 		gretlopt vopt = ml_robust_specifier(spec);
1569 
1570 		err = gretl_model_add_QML_vcv(pmod, MLE, spec->Hinv,
1571 					      G, spec->dset, vopt, NULL);
1572 	    } else {
1573 		err = gretl_model_add_OPG_vcv(pmod, G, NULL);
1574 	    }
1575 	}
1576 	gretl_matrix_free(G);
1577     }
1578 
1579     return err;
1580 }
1581 
1582 /* NLS: add coefficient covariance matrix and standard errors
1583    based on GNR */
1584 
add_full_std_errs_to_model(MODEL * pmod)1585 static int add_full_std_errs_to_model (MODEL *pmod)
1586 {
1587     double abst, tstat_max = 0;
1588     int i, k, err = 0;
1589 
1590     if (pmod->vcv == NULL) {
1591 	err = makevcv(pmod, pmod->sigma);
1592 	if (err) {
1593 	    return err;
1594 	}
1595     }
1596 
1597     for (i=0; i<pmod->ncoeff; i++) {
1598 	k = ijton(i, i, pmod->ncoeff);
1599 	if (pmod->vcv[k] < 0.0) {
1600 	    pmod->sderr[i] = NADBL;
1601 	} else {
1602 	    pmod->sderr[i] = sqrt(pmod->vcv[k]);
1603 	    abst = fabs(pmod->coeff[i] / pmod->sderr[i]);
1604 	    if (abst > tstat_max) {
1605 		tstat_max = abst;
1606 	    }
1607 	}
1608     }
1609 
1610     if (tstat_max > 0) {
1611 	gretl_model_set_double(pmod, "GNR_tmax", tstat_max);
1612     }
1613 
1614     return 0;
1615 }
1616 
1617 /* Experimental: watch out for bad stuff! Here we react
1618    to the case where there's machine-perfect collinearity
1619    in the Gauss-Newton Regression and one or more terms
1620    were dropped. We don't have standard errors for those
1621    terms but we do have coefficient estimates; we set
1622    the standard errors to NA. Note that @list here is
1623    the full list of regressors passed to the GNR.
1624 */
1625 
add_partial_std_errs_to_model(MODEL * pmod,const int * list)1626 static int add_partial_std_errs_to_model (MODEL *pmod,
1627 					  const int *list)
1628 {
1629     int ndrop = list[0] - pmod->list[0];
1630     double *coeff, *sderr;
1631     int k, *dlist;
1632     int i, j;
1633 
1634     if (ndrop <= 0) {
1635 	/* eh? reinstate the error */
1636 	fprintf(stderr, "no droplist found\n");
1637 	return E_JACOBIAN;
1638     }
1639 
1640     dlist = gretl_list_new(ndrop);
1641     gretl_list_diff(dlist, list, pmod->list);
1642 
1643     k = list[0] - 1;
1644     coeff = malloc(k * sizeof *coeff);
1645     sderr = malloc(k * sizeof *sderr);
1646 
1647     if (coeff == NULL || sderr == NULL) {
1648 	free(dlist);
1649 	return E_ALLOC;
1650     }
1651 
1652     j = 0;
1653     for (i=0; i<k; i++) {
1654 	if (in_gretl_list(dlist, i+2)) {
1655 	    /* missing, skip it */
1656 	    sderr[i] = NADBL;
1657 	} else {
1658 	    sderr[i] = pmod->sderr[j++];
1659 	}
1660     }
1661 
1662     free(pmod->coeff);
1663     pmod->coeff = coeff;
1664     free(pmod->sderr);
1665     pmod->sderr = sderr;
1666     pmod->ncoeff = k;
1667 
1668     /* clean up stuff we don't want */
1669     gretl_model_destroy_data_item(pmod, "droplist");
1670     free(pmod->xpx);
1671     pmod->xpx = NULL;
1672     free(pmod->vcv);
1673     pmod->vcv = NULL;
1674     free(dlist);
1675 
1676     /* and record the breakage */
1677     gretl_model_set_int(pmod, "broken-vcv", 1);
1678 
1679     fprintf(stderr, "added partial standard errors\n");
1680 
1681     return 0;
1682 }
1683 
add_GNR_std_errs_to_model(MODEL * pmod,const int * list)1684 static int add_GNR_std_errs_to_model (MODEL *pmod, const int *list)
1685 {
1686     int err;
1687 
1688     if (pmod->errcode == E_JACOBIAN) {
1689 	pmod->errcode = err = add_partial_std_errs_to_model(pmod, list);
1690     } else {
1691 	pmod->errcode = err = add_full_std_errs_to_model(pmod);
1692     }
1693 
1694     return err;
1695 }
1696 
1697 /* transcribe coefficient estimates into model struct */
1698 
add_coeffs_to_model(MODEL * pmod,double * coeff)1699 static void add_coeffs_to_model (MODEL *pmod, double *coeff)
1700 {
1701     int i;
1702 
1703     for (i=0; i<pmod->ncoeff; i++) {
1704 	pmod->coeff[i] = coeff[i];
1705     }
1706 }
1707 
1708 /* convert (back) from '%s - (%s)' to '%s = %s' */
1709 
adjust_saved_nlfunc(char * s)1710 static char *adjust_saved_nlfunc (char *s)
1711 {
1712     char *p = strchr(s, '-');
1713 
1714     if (p != NULL) {
1715 	*p = '=';
1716     }
1717 
1718     p = strchr(s, '(');
1719     if (p != NULL) {
1720 	shift_string_left(p, 1);
1721     }
1722 
1723     p = strrchr(s, ')');
1724     if (p != NULL) {
1725 	*p = '\0';
1726     }
1727 
1728     return s;
1729 }
1730 
1731  /* Attach additional specification info to make it possible to
1732     reconstruct the model from the saved state.  We need this
1733     for the "Modify model" option in the gretl GUI, and may
1734     also make use of it for bootstrapping NLS models.
1735  */
1736 
nl_model_add_spec_info(MODEL * pmod,nlspec * spec)1737 static int nl_model_add_spec_info (MODEL *pmod, nlspec *spec)
1738 {
1739     const char *cmd = gretl_command_word(spec->ci);
1740     PRN *prn;
1741     char *buf;
1742     int i, err = 0;
1743 
1744     prn = gretl_print_new(GRETL_PRINT_BUFFER, &err);
1745     if (err) {
1746 	return err;
1747     }
1748 
1749     pputs(prn, cmd);
1750 
1751     if (pmod->depvar != NULL) {
1752 	pprintf(prn, " %s\n", pmod->depvar);
1753     } else {
1754 	pputc(prn, '\n');
1755     }
1756 
1757     if (spec->naux > 0) {
1758 	gretl_model_set_int(pmod, "nl_naux", spec->naux);
1759     }
1760 
1761     for (i=0; i<spec->naux; i++) {
1762 	pprintf(prn, "%s\n", spec->aux[i]);
1763     }
1764 
1765     if (spec->ci == GMM) {
1766 	/* orthog, weights */
1767 	nlspec_print_gmm_info(spec, prn);
1768     }
1769 
1770     if (numeric_mode(spec)) {
1771 	pprintf(prn, "params");
1772 	for (i=0; i<spec->nparam; i++) {
1773 	    pprintf(prn, " %s", spec->params[i].name);
1774 	}
1775 	pputc(prn, '\n');
1776     } else {
1777 	for (i=0; i<spec->nparam; i++) {
1778 	    pprintf(prn, "deriv %s = %s\n", spec->params[i].name,
1779 		    spec->params[i].deriv);
1780 	}
1781     }
1782 
1783     if (spec->hesscall != NULL) {
1784 	pprintf(prn, "hessian %s\n", spec->hesscall);
1785     }
1786 
1787     pprintf(prn, "end %s\n", cmd);
1788 
1789     buf = gretl_print_steal_buffer(prn);
1790     gretl_model_set_string_as_data(pmod, "nlinfo", buf);
1791     gretl_print_destroy(prn);
1792 
1793     return 0;
1794 }
1795 
copy_user_parnames(MODEL * pmod,nlspec * spec)1796 static int copy_user_parnames (MODEL *pmod, nlspec *spec)
1797 {
1798     const char *sep = ",";
1799     const char *pname;
1800     char *tmp;
1801     int i, err = 0;
1802 
1803     if (spec->flags & NL_NAMES_ARRAY) {
1804 	/* we got an array of strings */
1805 	gretl_array *a = get_array_by_name(spec->parnames);
1806 	int ns = 0;
1807 
1808 	if (a != NULL) {
1809 	    char **S = gretl_array_get_strings(a, &ns);
1810 
1811 	    for (i=0; i<pmod->ncoeff && !err; i++) {
1812 		if (i < ns) {
1813 		    pmod->params[i] = gretl_strdup(S[i]);
1814 		} else {
1815 		    pmod->params[i] = gretl_strdup("unnamed");
1816 		}
1817 	    }
1818 	} else {
1819 	    err = E_DATA;
1820 	}
1821 	return err;
1822     }
1823 
1824     /* copy the user-defined string before applying strtok */
1825     tmp = gretl_strdup(spec->parnames);
1826     if (tmp == NULL) {
1827 	return E_ALLOC;
1828     }
1829 
1830     if (strchr(tmp, ',') == NULL) {
1831 	sep = " ";
1832     }
1833 
1834     for (i=0; i<pmod->ncoeff && !err; i++) {
1835 	pname = strtok((i == 0)? tmp : NULL, sep);
1836 	if (pname == NULL) {
1837 	    pmod->params[i] = gretl_strdup("unnamed");
1838 	} else {
1839 	    pmod->params[i] = gretl_strdup(pname);
1840 	    if (pmod->params[i] == NULL) {
1841 		err = E_ALLOC;
1842 	    }
1843 	}
1844     }
1845 
1846     free(tmp);
1847 
1848     return err;
1849 }
1850 
1851 /* Called for all of NLS, MLE, GMM: attach to the model struct
1852    the names of the parameters and some other string info
1853 */
1854 
add_param_names_to_model(MODEL * pmod,nlspec * spec)1855 static int add_param_names_to_model (MODEL *pmod, nlspec *spec)
1856 {
1857     char pname[VNAMELEN];
1858     int nc = pmod->ncoeff;
1859     int i, j, k, m, n;
1860     int err = 0;
1861 
1862     pmod->params = strings_array_new(nc);
1863     if (pmod->params == NULL) {
1864 	return E_ALLOC;
1865     }
1866 
1867     pmod->nparams = nc;
1868 
1869     if (spec->ci == NLS) {
1870 	pmod->depvar = gretl_strdup(spec->nlfunc);
1871 	if (pmod->depvar != NULL) {
1872 	    adjust_saved_nlfunc(pmod->depvar);
1873 	} else {
1874 	    err = E_ALLOC;
1875 	}
1876     } else if (spec->nlfunc != NULL) {
1877 	n = strlen(spec->nlfunc) + strlen(spec->lhname);
1878 	pmod->depvar = malloc(n + 4);
1879 	if (pmod->depvar != NULL) {
1880 	    sprintf(pmod->depvar, "%s = %s", spec->lhname, spec->nlfunc);
1881 	} else {
1882 	    err = E_ALLOC;
1883 	}
1884     }
1885 
1886     if (err) {
1887 	free(pmod->params);
1888 	return err;
1889     }
1890 
1891     if (spec->parnames != NULL) {
1892 	/* handle the case where the user has given a "parnames"
1893 	   string or strings array
1894 	*/
1895 	err = copy_user_parnames(pmod, spec);
1896     } else {
1897 	/* compose automatic parameter names */
1898 	i = 0;
1899 	for (j=0; j<spec->nparam && !err; j++) {
1900 	    if (scalar_param(spec, j)) {
1901 		pmod->params[i] = gretl_strdup(spec->params[j].name);
1902 		if (pmod->params[i] == NULL) {
1903 		    err = E_ALLOC;
1904 		}
1905 		i++;
1906 	    } else {
1907 		m = spec->params[j].nc;
1908 		sprintf(pname, "%d", m + 1);
1909 		n = VNAMELEN - strlen(pname) - 3;
1910 		for (k=0; k<m && !err; k++) {
1911 		    sprintf(pname, "%.*s[%d]", n, spec->params[j].name, k + 1);
1912 		    pmod->params[i] = gretl_strdup(pname);
1913 		    if (pmod->params[i] == NULL) {
1914 			err = E_ALLOC;
1915 		    }
1916 		    i++;
1917 		}
1918 	    }
1919 	}
1920     }
1921 
1922     if (!err && (spec->ci == NLS || gretl_in_gui_mode())) {
1923 	err = nl_model_add_spec_info(pmod, spec);
1924     }
1925 
1926     if (err && !pmod->errcode) {
1927 	pmod->errcode = err;
1928     }
1929 
1930     return err;
1931 }
1932 
add_fit_resid_to_nls_model(MODEL * pmod,nlspec * spec,int perfect)1933 static int add_fit_resid_to_nls_model (MODEL *pmod,
1934 				       nlspec *spec,
1935 				       int perfect)
1936 {
1937     DATASET *dset = spec->dset;
1938     int T = dset->n;
1939     int yno = spec->dv;
1940     double *tmp;
1941     int s, t;
1942     int err = 0;
1943 
1944     /* we need full-length arrays for uhat, yhat */
1945 
1946     tmp = realloc(pmod->uhat, T * sizeof *tmp);
1947     if (tmp == NULL) {
1948 	return E_ALLOC;
1949     } else {
1950 	pmod->uhat = tmp;
1951     }
1952 
1953     tmp = realloc(pmod->yhat, T * sizeof *tmp);
1954     if (tmp == NULL) {
1955 	return E_ALLOC;
1956     } else {
1957 	pmod->yhat = tmp;
1958     }
1959 
1960     /* OK, we got them, now transcribe */
1961 
1962     s = 0;
1963     for (t=0; t<T; t++) {
1964 	if (t < pmod->t1 || t > pmod->t2) {
1965 	    pmod->uhat[t] = pmod->yhat[t] = NADBL;
1966 	} else if (perfect) {
1967 	    pmod->uhat[t] = 0.0;
1968 	    pmod->yhat[t] = dset->Z[yno][t];
1969 	} else {
1970 	    pmod->uhat[t] = spec->fvec[s];
1971 	    pmod->yhat[t] = dset->Z[yno][t] - spec->fvec[s];
1972 	    s++;
1973 	}
1974     }
1975 
1976     if (perfect || (spec->flags & NL_AUTOREG)) {
1977 	pmod->rho = pmod->dw = NADBL;
1978     }
1979 
1980     return err;
1981 }
1982 
1983 /* this may be used later for generating out-of-sample forecasts --
1984    see nls_forecast() in forecast.c
1985 */
1986 
transcribe_nls_function(MODEL * pmod,const char * s)1987 static int transcribe_nls_function (MODEL *pmod, const char *s)
1988 {
1989     char *formula;
1990     int err = 0;
1991 
1992     /* skip "depvar - " */
1993     s += strcspn(s, " ") + 3;
1994 
1995     formula = gretl_strdup(s);
1996     if (s != NULL) {
1997 	gretl_model_set_string_as_data(pmod, "nl_regfunc", formula);
1998     } else {
1999 	err = E_ALLOC;
2000     }
2001 
2002     return err;
2003 }
2004 
finalize_nls_model(MODEL * pmod,nlspec * spec,int perfect,int * glist)2005 int finalize_nls_model (MODEL *pmod, nlspec *spec,
2006 			int perfect, int *glist)
2007 {
2008     DATASET *dset = spec->dset;
2009     int err = 0;
2010 
2011     pmod->ci = spec->ci;
2012     pmod->t1 = spec->t1;
2013     pmod->t2 = spec->t2;
2014     pmod->full_n = dset->n;
2015 
2016     pmod->smpl.t1 = spec->dset->t1;
2017     pmod->smpl.t2 = spec->dset->t2;
2018 
2019     err = add_GNR_std_errs_to_model(pmod, glist);
2020 
2021     add_stats_to_model(pmod, spec);
2022 
2023     if (!err) {
2024 	add_fit_resid_to_nls_model(pmod, spec, perfect);
2025     }
2026 
2027     if (!err) {
2028 	err = add_param_names_to_model(pmod, spec);
2029     }
2030 
2031     if (!err) {
2032 	ls_criteria(pmod);
2033 	pmod->fstt = pmod->chisq = NADBL;
2034 	add_coeffs_to_model(pmod, spec->coeff);
2035 	pmod->list[1] = spec->dv;
2036 
2037 	/* set additional data on model to be shipped out */
2038 	gretl_model_set_int(pmod, "iters", spec->iters);
2039 	gretl_model_set_double(pmod, "tol", spec->tol);
2040 	if (spec->nlfunc != NULL) {
2041 	    transcribe_nls_function(pmod, spec->nlfunc);
2042 	}
2043 	if (spec->flags & NL_AUTOREG) {
2044 	    gretl_model_set_int(pmod, "dynamic", 1);
2045 	}
2046 	pmod->opt = spec->opt;
2047     }
2048 
2049     return err;
2050 }
2051 
2052 #if NLS_DEBUG > 1
2053 
2054 static void
print_GNR_dataset(const int * list,DATASET * gdset)2055 print_GNR_dataset (const int *list, DATASET *gdset)
2056 {
2057     PRN *prn = gretl_print_new(GRETL_PRINT_STDERR, NULL);
2058     int t1 = gdset->t1;
2059 
2060     fprintf(stderr, "gdset->t1 = %d, gdset->t2 = %d\n",
2061 	    gdset->t1, gdset->t2);
2062     gdset->t1 = 0;
2063     printdata(list, NULL, gdset, OPT_O, prn);
2064     gdset->t1 = t1;
2065     gretl_print_destroy(prn);
2066 }
2067 
2068 #endif
2069 
2070 /* Gauss-Newton regression to calculate standard errors for the NLS
2071    parameters (see Davidson and MacKinnon).  This model is taken
2072    as the basis for the model struct returned by the "nls" command.
2073 */
2074 
GNR(int * glist,DATASET * gdset,gretlopt opt,PRN * prn)2075 MODEL GNR (int *glist, DATASET *gdset, gretlopt opt, PRN *prn)
2076 {
2077     gretlopt lsqopt = OPT_A;
2078     MODEL gnr;
2079 
2080     if (opt & OPT_R) {
2081 	/* robust variance matrix, if wanted */
2082 	lsqopt |= OPT_R;
2083     }
2084 
2085     gnr = lsq(glist, gdset, OLS, lsqopt);
2086 
2087 #if NLS_DEBUG
2088     gnr.name = gretl_strdup("Gauss-Newton Regression for NLS");
2089     printmodel(&gnr, gdset, OPT_NONE, prn);
2090     free(gnr.name);
2091     gnr.name = NULL;
2092 #endif
2093 
2094     if (gnr.errcode) {
2095 	pputs(prn, _("In Gauss-Newton Regression:\n"));
2096 	errmsg(gnr.errcode, prn);
2097     } else if (gnr.list[0] < glist[0]) {
2098 	/* excessive collinearity */
2099 #if HAVE_GMP
2100 	MODEL mpmod = mp_ols(glist, gdset, OPT_A);
2101 
2102 	if (mpmod.errcode) {
2103 	    /* back-track if mp_ols failed */
2104 	    fprintf(stderr, "nls: using MP for Jacobian failed (err=%d)\n",
2105 		    mpmod.errcode);
2106 	    clear_model(&mpmod);
2107 	    gnr.errcode = E_JACOBIAN;
2108 	    gretl_model_set_int(&gnr, "near-singular", 2);
2109 	} else {
2110 	    clear_model(&gnr);
2111 	    gnr = mpmod;
2112 	    if (lsqopt & OPT_R) {
2113 		gretl_model_set_int(&gnr, "non-robust", 1);
2114 	    }
2115 	    gretl_model_set_int(&gnr, "near-singular", 1);
2116 	}
2117 #else
2118 	gnr.errcode = E_JACOBIAN;
2119 	gretl_model_set_int(&gnr, "near-singular", 2);
2120 #endif
2121     }
2122 
2123     return gnr;
2124 }
2125 
make_GNR_dataset(nlspec * spec,DATASET * dset,int ** pglist,int * perfect,PRN * prn,int * err)2126 static DATASET *make_GNR_dataset (nlspec *spec,
2127 				  DATASET *dset,
2128 				  int **pglist,
2129 				  int *perfect,
2130 				  PRN *prn,
2131 				  int *err)
2132 {
2133     double *uhat = spec->fvec;
2134     DATASET *gdset = NULL;
2135     int *glist;
2136     int i, j, t, v;
2137     int T = spec->nobs;
2138 
2139     if (gretl_iszero(0, T - 1, uhat)) {
2140 	pputs(prn, _("Perfect fit achieved\n"));
2141 	*perfect = 1;
2142 	for (t=0; t<spec->nobs; t++) {
2143 	    uhat[t] = 1.0; /* will be adjusted later */
2144 	}
2145 	spec->crit = 0.0;
2146     }
2147 
2148     /* number of variables = const + depvar + spec->ncoeff
2149        (derivatives) */
2150     gdset = create_auxiliary_dataset(2 + spec->ncoeff, T, 0);
2151     glist = gretl_consecutive_list_new(1, spec->ncoeff + 1);
2152 
2153     if (gdset == NULL || glist == NULL) {
2154 	destroy_dataset(gdset);
2155 	free(glist);
2156 	*err = E_ALLOC;
2157 	return NULL;
2158     }
2159 
2160     if (dataset_is_time_series(dset)) {
2161 	gdset->structure = dset->structure;
2162 	gdset->pd = dset->pd;
2163 	ntolabel(gdset->stobs, dset->t1, dset);
2164 	gdset->sd0 = get_date_x(gdset->pd, gdset->stobs);
2165     }
2166 
2167     /* dependent variable (NLS residual): write into
2168        slot 1 in gdset */
2169     strcpy(gdset->varname[1], "gnr_y");
2170     for (t=0; t<T; t++) {
2171 	gdset->Z[1][t] = uhat[t];
2172     }
2173 
2174     /* independent variables: derivatives wrt NLS params,
2175        starting at slot 2 in gdset */
2176     for (i=0; i<spec->ncoeff; i++) {
2177 	sprintf(gdset->varname[i+2], "gnr_x%d", i + 1);
2178     }
2179     if (analytic_mode(spec)) {
2180 	get_nls_derivs(T, NULL, gdset, spec);
2181     } else {
2182 	for (i=0; i<spec->ncoeff; i++) {
2183 	    v = i + 2;
2184 	    j = T * i; /* offset into jac array */
2185 	    for (t=0; t<T; t++) {
2186 		gdset->Z[v][t] = spec->J->val[j++];
2187 	    }
2188 	}
2189     }
2190 
2191 #if NLS_DEBUG > 1
2192     printlist(glist, "glist");
2193     print_GNR_dataset(glist, gdset);
2194 #endif
2195 
2196     *pglist = glist;
2197 
2198     return gdset;
2199 }
2200 
2201 /* allocate space to copy info into model struct */
2202 
nl_model_allocate(MODEL * pmod,nlspec * spec)2203 static int nl_model_allocate (MODEL *pmod, nlspec *spec)
2204 {
2205     int k = spec->ncoeff;
2206 
2207     if (spec->opt & OPT_A) {
2208 	/* "auxiliary" model: no variance matrix, but
2209 	   we need sderr to prevent crash on printout
2210 	*/
2211 	pmod->vcv = NULL;
2212 	pmod->coeff = malloc(k * sizeof *pmod->coeff);
2213 	pmod->sderr = malloc(k * sizeof *pmod->sderr);
2214 	if (pmod->coeff == NULL || pmod->sderr == NULL) {
2215 	    pmod->errcode = E_ALLOC;
2216 	}
2217     } else {
2218 	int nvc = (k * k + k) / 2;
2219 
2220 	pmod->coeff = malloc(k * sizeof *pmod->coeff);
2221 	pmod->sderr = malloc(k * sizeof *pmod->sderr);
2222 	pmod->vcv = malloc(nvc * sizeof *pmod->vcv);
2223 
2224 	if (pmod->coeff == NULL ||
2225 	    pmod->sderr == NULL ||
2226 	    pmod->vcv == NULL) {
2227 	    pmod->errcode = E_ALLOC;
2228 	}
2229     }
2230 
2231     if (pmod->errcode == 0) {
2232 	pmod->ncoeff = k;
2233     }
2234 
2235     return pmod->errcode;
2236 }
2237 
2238 /* Work up the results of estimation into the form of a gretl
2239    MODEL struct.  This is used for MLE and GMM; in the case of
2240    NLS the Gauss-Newton regression provides the basis for the
2241    final model structure.
2242 */
2243 
make_other_nl_model(MODEL * pmod,nlspec * spec,const DATASET * dset)2244 static int make_other_nl_model (MODEL *pmod,
2245 				nlspec *spec,
2246 				const DATASET *dset)
2247 {
2248     nl_model_allocate(pmod, spec);
2249     if (pmod->errcode) {
2250 	return pmod->errcode;
2251     }
2252 
2253     pmod->t1 = spec->t1;
2254     pmod->t2 = spec->t2;
2255     pmod->nobs = spec->nobs;
2256 
2257     /* hmm */
2258     pmod->dfn = pmod->ncoeff;
2259     pmod->dfd = pmod->nobs - pmod->ncoeff;
2260 
2261     pmod->ci = spec->ci;
2262 
2263     if (spec->ci == MLE) {
2264 	pmod->lnL = spec->crit;
2265     } else {
2266 	/* GMM */
2267 	pmod->lnL = NADBL;
2268     }
2269 
2270     mle_criteria(pmod, 0);
2271     add_coeffs_to_model(pmod, spec->coeff);
2272 
2273     if (spec->ci == GMM && (spec->opt & OPT_G)) {
2274 	; /* IVREG via GMM */
2275     } else {
2276 	pmod->errcode = add_param_names_to_model(pmod, spec);
2277     }
2278 
2279     if (!pmod->errcode) {
2280 	if (pmod->ci == MLE) {
2281 	    pmod->errcode = mle_add_vcv(pmod, spec);
2282 	} else {
2283 	    pmod->errcode = gmm_add_vcv(pmod, spec);
2284 	}
2285     }
2286 
2287     if (!pmod->errcode && pmod->ci == GMM) {
2288 	maybe_add_gmm_residual(pmod, spec, dset);
2289     }
2290 
2291     if (!pmod->errcode) {
2292 	if (spec->flags & NL_NEWTON) {
2293 	    gretl_model_set_int(pmod, "iters", spec->fncount);
2294 	} else {
2295 	    gretl_model_set_int(pmod, "fncount", spec->fncount);
2296 	    gretl_model_set_int(pmod, "grcount", spec->grcount);
2297 	    gretl_model_set_double(pmod, "tol", spec->tol);
2298 	}
2299     }
2300 
2301     /* mask invalid stats */
2302     pmod->sigma = NADBL;
2303     pmod->rsq = pmod->adjrsq = NADBL;
2304     pmod->fstt = pmod->chisq = NADBL;
2305     pmod->rho = pmod->dw = NADBL;
2306 
2307     return pmod->errcode;
2308 }
2309 
add_nls_coeffs(MODEL * pmod,nlspec * spec)2310 static int add_nls_coeffs (MODEL *pmod, nlspec *spec)
2311 {
2312     pmod->ncoeff = spec->ncoeff;
2313     pmod->full_n = 0;
2314 
2315     pmod->errcode = gretl_model_allocate_storage(pmod);
2316 
2317     if (!pmod->errcode) {
2318 	add_coeffs_to_model(pmod, spec->coeff);
2319     }
2320 
2321     return pmod->errcode;
2322 }
2323 
2324 /* free up resources associated with the nlspec struct */
2325 
clear_nlspec(nlspec * spec)2326 static void clear_nlspec (nlspec *spec)
2327 {
2328     int i;
2329 
2330     if (spec == NULL) {
2331 	return;
2332     }
2333 
2334     free(spec->parnames);
2335     spec->parnames = NULL;
2336 
2337     if (spec->params != NULL) {
2338 	for (i=0; i<spec->nparam; i++) {
2339 	    free(spec->params[i].deriv);
2340 	}
2341 	free(spec->params);
2342 	spec->params = NULL;
2343     }
2344     spec->nparam = 0;
2345 
2346     free(spec->fvec);
2347     spec->fvec = NULL;
2348 
2349     gretl_matrix_free(spec->J);
2350     spec->J = NULL;
2351 
2352     free(spec->coeff);
2353     spec->coeff = NULL;
2354     spec->ncoeff = 0;
2355     spec->nvec = 0;
2356 
2357     if (spec->aux != NULL) {
2358 	for (i=0; i<spec->naux; i++) {
2359 	    free(spec->aux[i]);
2360 	}
2361 	free(spec->aux);
2362 	spec->aux = NULL;
2363     }
2364     spec->naux = 0;
2365 
2366     if (spec->genrs != NULL) {
2367 	for (i=0; i<spec->ngenrs; i++) {
2368 	    destroy_genr(spec->genrs[i]);
2369 	}
2370 	free(spec->genrs);
2371 	spec->genrs = NULL;
2372     }
2373     spec->ngenrs = 0;
2374     spec->generr = 0;
2375 
2376     if (spec->hgen != NULL) {
2377 	destroy_genr(spec->hgen);
2378 	spec->hgen = NULL;
2379     }
2380 
2381     if (spec->hesscall != NULL) {
2382 	free(spec->hesscall);
2383 	spec->hesscall = NULL;
2384     }
2385 
2386     free(spec->nlfunc);
2387     spec->nlfunc = NULL;
2388 
2389     gretl_matrix_free(spec->Hinv);
2390     spec->Hinv = NULL;
2391 
2392     spec->flags = 0;
2393     spec->opt = OPT_NONE;
2394 
2395     spec->dv = 0;
2396     spec->lhtype = GRETL_TYPE_NONE;
2397     spec->lhv = 0;
2398     spec->lvec = NULL;
2399 
2400     spec->lhname[0] = '\0';
2401     spec->hname[0] = '\0';
2402 
2403     spec->iters = 0;
2404     spec->fncount = 0;
2405     spec->grcount = 0;
2406 
2407     spec->t1 = spec->t2 = 0;
2408     spec->real_t1 = spec->real_t2 = 0;
2409     spec->nobs = 0;
2410 
2411     spec->dset = NULL;
2412     spec->prn = NULL;
2413 
2414     if (spec->oc != NULL) {
2415 	oc_set_destroy(spec->oc);
2416 	spec->oc = NULL;
2417     }
2418 
2419     free(spec->missmask);
2420     spec->missmask = NULL;
2421 }
2422 
2423 /*
2424    Next block: functions that interface with minpack.
2425 
2426    The details below may be obscure, but here's the basic idea: The
2427    minpack functions are passed an array ("fvec") that holds the
2428    calculated values of the function to be minimized, at a given value
2429    of the parameters, and also (in the case of analytic derivatives)
2430    an array holding the Jacobian ("jac").  Minpack is also passed a
2431    callback function that will recompute the values in these arrays,
2432    given a revised vector of parameter estimates.
2433 
2434    As minpack does its iterative thing, at each step it invokes the
2435    callback function, supplying its updated parameter estimates and
2436    saying via a flag variable ("iflag") whether it wants the function
2437    itself or the Jacobian re-evaluated.
2438 
2439    The libgretl strategy involves holding all the relevant values (nls
2440    residual, nls derivatives, and nls parameters) as variables in a
2441    gretl dataset (Z-array and datainfo-struct pair).  The callback
2442    function that we supply to minpack first transcribes the revised
2443    parameter estimates into the dataset, then invokes genr() to
2444    recalculate the residual and derivatives, then transcribes the
2445    results back into the fvec and jac arrays.
2446 */
2447 
2448 /* callback for lm_calculate (below) to be used by minpack */
2449 
nls_calc(int m,int n,double * x,double * fvec,double * jac,int ldjac,int * iflag,void * p)2450 static int nls_calc (int m, int n, double *x, double *fvec,
2451 		     double *jac, int ldjac, int *iflag,
2452 		     void *p)
2453 {
2454     nlspec *s = (nlspec *) p;
2455     int err;
2456 
2457 #if NLS_DEBUG
2458     fprintf(stderr, "nls_calc called by minpack with iflag = %d\n",
2459 	    (int) *iflag);
2460 #endif
2461 
2462     /* write current coefficient values into dataset */
2463     update_coeff_values(x, s);
2464 
2465     if (*iflag == 1) {
2466 	/* calculate function at x, results into fvec */
2467 	err = nl_function_calc(fvec, x, p);
2468 	if (err) {
2469 	    fprintf(stderr, "nl_function_calc: err = %d\n", err);
2470 	    *iflag = -1;
2471 	}
2472     } else if (*iflag == 2) {
2473 	/* calculate jacobian at x, results into jac */
2474 	err = get_nls_derivs(m, jac, NULL, p);
2475 	if (err) {
2476 	    fprintf(stderr, "get_nls_derivs: err = %d\n", err);
2477 	    *iflag = -1;
2478 	}
2479     }
2480 
2481     return 0;
2482 }
2483 
2484 /* Below: copied here from minpack chkder.c, with a view to
2485    figuring if it could be improved (lessening the chance
2486    of false alarms for correct derivatives).
2487 */
2488 
chkder(const double * x,double * xp,const double * fvec,const double * fvecp,const gretl_matrix * J,int mode,double * err)2489 static int chkder (const double *x,
2490 		   double *xp,
2491 		   const double *fvec,
2492 		   const double *fvecp,
2493 		   const gretl_matrix *J,
2494 		   int mode,
2495 		   double *err)
2496 {
2497     const double epsmch = DBL_EPSILON;
2498     double temp, eps = sqrt(epsmch);
2499     int i, j;
2500 
2501     if (mode == 1) {
2502 	/* mode 1: construct a neighboring vector, xp */
2503 	for (j=0; j<J->cols; j++) {
2504 	    temp = eps * fabs(x[j]);
2505 	    if (temp == 0.0) {
2506 		temp = eps;
2507 	    }
2508 	    xp[j] = x[j] + temp;
2509 	}
2510     } else {
2511 	/* mode 2: assess validity of gradient */
2512 	const double factor = 100;
2513 	double d, epsf = factor * epsmch;
2514 	double epslog = log10(eps);
2515 
2516 	for (i=0; i<J->rows; i++) {
2517 	    err[i] = 0.0;
2518 	}
2519 	for (j=0; j<J->cols; j++) {
2520 	    temp = fabs(x[j]);
2521 	    if (temp == 0.0) {
2522 		temp = 1.0;
2523 	    }
2524 	    for (i=0; i<J->rows; i++) {
2525 		err[i] += temp * gretl_matrix_get(J, i, j);
2526 	    }
2527 	}
2528 	for (i=0; i<J->rows; i++) {
2529 	    temp = 1.0;
2530 	    d = fabs(fvecp[i] - fvec[i]);
2531 	    if (fvec[i] != 0.0 && fvecp[i] != 0.0 &&
2532 		d >= epsf * fabs(fvec[i])) {
2533 		d = fabs((fvecp[i] - fvec[i]) / eps - err[i]);
2534 		temp = eps * d / (fabs(fvec[i]) + fabs(fvecp[i]));
2535 	    }
2536 	    err[i] = 1.0;
2537 	    if (temp > epsmch && temp < eps) {
2538 		err[i] = (log10(temp) - epslog) / epslog;
2539 	    }
2540 	    if (temp >= eps) {
2541 		err[i] = 0.0;
2542 	    }
2543 	}
2544     }
2545 
2546     return 0;
2547 }
2548 
2549 /* in case the user supplied analytical derivatives for the
2550    parameters, check them for sanity */
2551 
check_derivatives(nlspec * spec,PRN * prn)2552 static int check_derivatives (nlspec *spec, PRN *prn)
2553 {
2554     double *x = spec->coeff;
2555     double *fvec = spec->fvec;
2556     double *jac = spec->J->val;
2557     int m = spec->nobs;
2558     int n = spec->ncoeff;
2559     int ldjac = m;
2560     int iflag;
2561     double *xp, *xerr, *fvecp;
2562     int i, badcount = 0, zerocount = 0;
2563 
2564     /* note: allocate space for xerr and fvecp too */
2565     xp = malloc((n + m + m) * sizeof *xp);
2566     if (xp == NULL) {
2567 	return E_ALLOC;
2568     }
2569 
2570     xerr = xp + n;
2571     fvecp = xerr + m;
2572 
2573 #if GRAD_DEBUG
2574     fprintf(stderr, "\nchkder, starting: m=%d, n=%d, ldjac=%d\n",
2575 	    (int) m, (int) n, (int) ldjac);
2576     for (i=0; i<spec->ncoeff; i++) {
2577 	fprintf(stderr, "x[%d] = %.9g\n", i+1, x[i]);
2578     }
2579     for (i=0; i<spec->nobs; i++) {
2580 	fprintf(stderr, "fvec[%d] = %.9g\n", i+1, fvec[i]);
2581     }
2582 #endif
2583 
2584     /* mode 1: x contains the point of evaluation of the function; on
2585        output xp is set to a neighboring point. */
2586     chkder(x, xp, fvec, fvecp, spec->J, 1, xerr);
2587 
2588     /* calculate gradient */
2589     iflag = 2;
2590     nls_calc(m, n, x, fvec, jac, ldjac, &iflag, spec);
2591     if (iflag == -1) goto chkderiv_abort;
2592 
2593 #if GRAD_DEBUG
2594     gretl_matrix_print(spec->J, "spec->J");
2595 #endif
2596 
2597     /* calculate function, at neighboring point xp */
2598     iflag = 1;
2599     nls_calc(m, n, xp, fvecp, jac, ldjac, &iflag, spec);
2600     if (iflag == -1) goto chkderiv_abort;
2601 
2602     /* mode 2: on input, fvec must contain the functions, the rows of
2603        fjac must contain the gradients evaluated at x, and fvecp must
2604        contain the functions evaluated at xp.  On output, xerr contains
2605        measures of correctness of the respective gradients.
2606     */
2607     chkder(x, xp, fvec, fvecp, spec->J, 2, xerr);
2608 
2609 #if GRAD_DEBUG
2610     fprintf(stderr, "\nchkder, done mode 2:\n");
2611     for (i=0; i<m; i++) {
2612 	fprintf(stderr, "%d: dfvec %g, xerr = %g\n",
2613 		i+1, fvecp[i] - fvec[i], xerr[i]);
2614     }
2615 #endif
2616 
2617     /* examine "xerr" vector */
2618     for (i=0; i<m; i++) {
2619 	if (xerr[i] == 0.0) {
2620 	    zerocount++;
2621 	} else if (xerr[i] < 0.35) {
2622 	    badcount++;
2623 	}
2624     }
2625 
2626     if (zerocount > 0) {
2627 	gretl_errmsg_set(_("NLS: The supplied derivatives seem to be incorrect"));
2628 	fprintf(stderr, _("%d out of %d tests gave zero\n"), zerocount, (int) m);
2629     } else if (badcount > 0) {
2630 	pputs(prn, _("Warning: The supplied derivatives may be incorrect, or perhaps\n"
2631 		     "the data are ill-conditioned for this function.\n"));
2632 	pprintf(prn, _("%d out of %d gradients looked suspicious.\n\n"),
2633 		badcount, (int) m);
2634     }
2635 
2636  chkderiv_abort:
2637 
2638     free(xp);
2639 
2640     return (zerocount > m / 4);
2641 }
2642 
2643 /* drivers for BFGS code below, first for MLE */
2644 
mle_calculate(nlspec * s,PRN * prn)2645 static int mle_calculate (nlspec *s, PRN *prn)
2646 {
2647     BFGS_GRAD_FUNC gradfunc = NULL;
2648     HESS_FUNC hessfunc = NULL;
2649     int maxit, use_newton = 0;
2650     int err = 0;
2651 
2652     if (libset_get_int(GRETL_OPTIM) == OPTIM_NEWTON) {
2653 	use_newton = 1;
2654     }
2655 
2656     if (analytic_mode(s) && !suppress_grad_check(s)) {
2657 	err = check_derivatives(s, prn);
2658     }
2659 
2660     if (!err) {
2661 	if (analytic_mode(s)) {
2662 	    gradfunc = get_mle_gradient;
2663 	}
2664 	if (s->hesscall != NULL) {
2665 	    hessfunc = get_mle_hessian;
2666 	    s->flags |= NL_AHESS;
2667 	    if (!(s->opt & (OPT_G | OPT_R | OPT_C))) {
2668 		/* default to Hessian unless we got a
2669 		   conflicting option flag */
2670 		s->opt |= OPT_H;
2671 	    }
2672 	}
2673     }
2674 
2675     if (!err && use_newton) {
2676 	double crittol = 1.0e-7;
2677 	double gradtol = 1.0e-7;
2678 
2679 	maxit = 100;
2680 	s->flags |= NL_NEWTON;
2681 	err = newton_raphson_max(s->coeff, s->ncoeff, maxit,
2682 				 crittol, gradtol, &s->fncount,
2683 				 C_LOGLIK, get_mle_ll,
2684 				 gradfunc, hessfunc, s,
2685 				 s->opt, s->prn);
2686     } else if (!err) {
2687 	maxit = 500;
2688 	err = BFGS_max(s->coeff, s->ncoeff, maxit, s->tol,
2689 		       &s->fncount, &s->grcount,
2690 		       get_mle_ll, C_LOGLIK, gradfunc, s,
2691 		       NULL, s->opt, s->prn);
2692     }
2693 
2694     if (!err && (s->opt & (OPT_H | OPT_R | OPT_C))) {
2695 	/* doing Hessian or QML covariance matrix */
2696 	if (hessfunc != NULL) {
2697 	    s->Hinv = mle_hessian_inverse(s, &err);
2698 	} else {
2699 	    /* Note 2018-10-05: changed the condition for using
2700 	       hessian_inverse_from_score(): we were requiring
2701 	       both analytic_mode and that the loglikelihood
2702 	       function returns per-observation values (not just
2703 	       a scalar). But it seems the latter requirement,
2704 	       !scalar_loglik(s), is not really necessary.
2705 	    */
2706 	    if (analytic_mode(s)) {
2707 		s->Hinv = hessian_inverse_from_score(s->coeff, s->ncoeff,
2708 						     gradfunc, get_mle_ll,
2709 						     s, &err);
2710 	    } else {
2711 		double d = 0.01; /* adjust? */
2712 
2713 		s->Hinv = numerical_hessian_inverse(s->coeff, s->ncoeff,
2714 						    get_mle_ll, s, d, &err);
2715 	    }
2716 	}
2717 
2718 	if (err && !scalar_loglik(s)) {
2719 	    pprintf(prn, _("\nError: Hessian non-negative definite? (err = %d); "
2720 			  "dropping back to OPG\n"), err);
2721 	    s->opt &= ~OPT_H;
2722 	    s->opt &= ~OPT_R;
2723 	    err = 0;
2724 	}
2725     }
2726 
2727     return err;
2728 }
2729 
2730 /* Minpack driver for the case where analytical derivatives have been
2731    supplied */
2732 
lm_calculate(nlspec * spec,PRN * prn)2733 static int lm_calculate (nlspec *spec, PRN *prn)
2734 {
2735     int m = spec->nobs;
2736     int n = spec->ncoeff;
2737     int lwa = 5 * n + m; /* work array size */
2738     int ldjac = m;       /* leading dimension of jac array */
2739     int info = 0;
2740     int nfev = 0;
2741     int njev = 0;
2742     int *ipvt;
2743     double *wa;
2744     double factor;
2745     double ftol, xtol, gtol;
2746     int mode, maxfev, nprint;
2747     int err = 0;
2748 
2749     wa = malloc(lwa * sizeof *wa);
2750     ipvt = malloc(n * sizeof *ipvt);
2751 
2752     if (wa == NULL || ipvt == NULL) {
2753 	err = E_ALLOC;
2754 	goto nls_cleanup;
2755     }
2756 
2757     if (!suppress_grad_check(spec)) {
2758 	err = check_derivatives(spec, prn);
2759 	if (err) {
2760 	    goto nls_cleanup;
2761 	}
2762     }
2763 
2764     /* mostly use the lmder1() defaults */
2765     maxfev = 100 * (n + 1);
2766     nprint = 0;
2767     mode = 1;
2768     ftol = xtol = spec->tol;
2769     gtol = 0.0;
2770     factor = 100; /* default */
2771 
2772     if (spec->flags & NL_SMALLSTEP) {
2773 	/* try to ensure a shorter step-length */
2774 	factor = 1.0;
2775     }
2776 
2777     /* call minpack */
2778     lmder_(nls_calc, m, n, spec->coeff, spec->fvec, spec->J->val, ldjac,
2779 	   ftol, xtol, gtol, maxfev, wa, mode, factor, nprint,
2780 	   &info, &nfev, &njev, ipvt, wa + n, wa + 2*n, wa + 3*n,
2781 	   wa + 4*n, wa + 5*n, spec);
2782 
2783     switch (info) {
2784     case -1:
2785 	err = 1;
2786 	break;
2787     case 0:
2788 	gretl_errmsg_set(_("Invalid NLS specification"));
2789 	err = 1;
2790 	break;
2791     case 1:
2792     case 2:
2793     case 3:
2794     case 4:
2795 	break;
2796     case 5:
2797     case 6:
2798     case 7:
2799 	gretl_errmsg_sprintf(_("NLS: failed to converge after %d iterations"),
2800 			     spec->iters);
2801 	err = 1;
2802 	break;
2803     default:
2804 	break;
2805     }
2806 
2807  nls_cleanup:
2808 
2809     free(wa);
2810     free(ipvt);
2811 
2812     return err;
2813 }
2814 
2815 /* callback for lm_approximate (below) to be used by minpack */
2816 
2817 static int
nls_calc_approx(int m,int n,double * x,double * fvec,int * iflag,void * p)2818 nls_calc_approx (int m, int n, double *x, double *fvec,
2819 		 int *iflag, void *p)
2820 {
2821     int erru, errc, err;
2822 
2823     /* write current parameter values into dataset Z */
2824     err = erru = update_coeff_values(x, p);
2825 
2826     /* calculate function at x, results into fvec */
2827     if (!err) {
2828 	err = errc = nl_function_calc(fvec, x, p);
2829     }
2830 
2831     if (err) {
2832 	/* flag error to minpack */
2833 	fprintf(stderr, "nls_calc_approx: got error %d from %s\n",
2834 		err, (erru)? "update_coeff_values" :
2835 		"nl_function_calc");
2836 	*iflag = -1;
2837     }
2838 
2839     return 0;
2840 }
2841 
2842 /* Minpack driver for the case where the Jacobian must be approximated
2843    numerically */
2844 
lm_approximate(nlspec * spec,PRN * prn)2845 static int lm_approximate (nlspec *spec, PRN *prn)
2846 {
2847     int m = spec->nobs;
2848     int n = spec->ncoeff;
2849     int ldjac = m;
2850     int info = 0;
2851     int maxfev = 200 * (n + 1); /* max iterations */
2852     int mode = 1, nprint = 0, nfev = 0;
2853     int iflag = 0;
2854     int *ipvt;
2855     double gtol = 0.0;
2856     double epsfcn = 0.0, factor = 100.;
2857     double *dspace, *diag, *qtf;
2858     double *wa1, *wa2, *wa3, *wa4;
2859     int err = 0;
2860 
2861     dspace = malloc((5 * n + m) * sizeof *dspace);
2862     ipvt = malloc(n * sizeof *ipvt);
2863 
2864     if (dspace == NULL || ipvt == NULL) {
2865 	err = E_ALLOC;
2866 	goto nls_cleanup;
2867     }
2868 
2869     diag = dspace;
2870     qtf = diag + n;
2871     wa1 = qtf + n;
2872     wa2 = wa1 + n;
2873     wa3 = wa2 + n;
2874     wa4 = wa3 + n;
2875 
2876     /* call minpack */
2877     lmdif_(nls_calc_approx, m, n, spec->coeff, spec->fvec,
2878 	   spec->tol, spec->tol, gtol, maxfev, epsfcn, diag,
2879 	   mode, factor, nprint, &info, &nfev, spec->J->val, ldjac,
2880 	   ipvt, qtf, wa1, wa2, wa3, wa4, spec);
2881 
2882     spec->iters = nfev;
2883 
2884     switch ((int) info) {
2885     case -1:
2886 	err = 1;
2887 	break;
2888     case 0:
2889 	gretl_errmsg_set(_("Invalid NLS specification"));
2890 	err = 1;
2891 	break;
2892     case 1:
2893     case 2:
2894     case 3:
2895     case 4:
2896 	break;
2897     case 5:
2898     case 6:
2899     case 7:
2900     case 8:
2901 	gretl_errmsg_sprintf(_("NLS: failed to converge after %d iterations"),
2902 			     spec->iters);
2903 	err = 1;
2904 	break;
2905     default:
2906 	break;
2907     }
2908 
2909     if (!err) {
2910 	double ess = spec->crit;
2911 	int iters = spec->iters;
2912 	gretlopt opt = spec->opt;
2913 
2914 	spec->opt = OPT_NONE;
2915 
2916 	/* call minpack again */
2917 	fdjac2_(nls_calc_approx, m, n, 0, spec->coeff, spec->fvec,
2918 		spec->J->val, ldjac, &iflag, epsfcn, wa4, spec);
2919 	spec->crit = ess;
2920 	spec->iters = iters;
2921 	spec->opt = opt;
2922     }
2923 
2924  nls_cleanup:
2925 
2926     free(dspace);
2927     free(ipvt);
2928 
2929     return err;
2930 }
2931 
2932 /* below: various public functions */
2933 
2934 /**
2935  * nlspec_add_param_with_deriv:
2936  * @spec: pointer to nls specification.
2937  * @s: string specifying a derivative with respect to a
2938  *   parameter of the regression function.
2939  *
2940  * Adds an analytical derivative to @spec.  This pointer must
2941  * have previously been obtained by a call to nlspec_new().
2942  * The required format for @dstr is "%varname = %formula", where
2943  * %varname is the name of the (scalar) variable holding the parameter
2944  * in question, and %formula is an expression, of the sort that
2945  * is fed to gretl's %genr command, giving the derivative of the
2946  * regression function in @spec with respect to the parameter.
2947  * The variable holding the parameter must be already present in
2948  * the dataset.
2949  *
2950  * Returns: 0 on success, non-zero error code on error.
2951  */
2952 
nlspec_add_param_with_deriv(nlspec * spec,const char * s)2953 int nlspec_add_param_with_deriv (nlspec *spec, const char *s)
2954 {
2955     const char *p = s;
2956     char *name = NULL;
2957     char *deriv = NULL;
2958     gretl_bundle *b = NULL;
2959     GretlType type = 0;
2960     int err = 0;
2961 
2962     if (spec->ci == GMM) {
2963 	gretl_errmsg_set(_("Analytical derivatives cannot be used with GMM"));
2964 	return E_DATA;
2965     }
2966 
2967     if (!strncmp(p, "deriv ", 6)) {
2968 	/* make starting with "deriv" optional */
2969 	p += 6;
2970     }
2971 
2972     err = equation_get_lhs_and_rhs(p, &name, &deriv);
2973     if (err) {
2974 	fprintf(stderr, "parse error in deriv string: '%s'\n", s);
2975 	return E_PARSE;
2976     }
2977 
2978     err = check_param_name(&name, &type, &b);
2979 
2980     if (!err) {
2981 	err = nlspec_push_param(spec, name, type, b, deriv);
2982 	if (err) {
2983 	    free(deriv);
2984 	    deriv = NULL;
2985 	}
2986     }
2987 
2988     free(name);
2989 
2990     if (!err) {
2991 	set_analytic_mode(spec);
2992     }
2993 
2994     return err;
2995 }
2996 
nlspec_add_hessian(nlspec * spec,const char * hesscall)2997 static int nlspec_add_hessian (nlspec *spec, const char *hesscall)
2998 {
2999     int err;
3000 
3001     if (spec->ci != MLE) {
3002 	/* we only do this for MLE */
3003 	return E_TYPES;
3004     }
3005 
3006     if (*spec->hname != '\0') {
3007 	/* Hessian already added */
3008 	return E_DATA;
3009     }
3010 
3011     err = optimizer_get_matrix_name(hesscall, spec->hname);
3012 
3013     if (!err) {
3014 	spec->hesscall = gretl_strdup(hesscall);
3015 	if (spec->hesscall == NULL) {
3016 	    err = E_ALLOC;
3017 	}
3018     }
3019 
3020     return err;
3021 }
3022 
screen_bad_aux(const char * line,const DATASET * dset,int * pci)3023 static int screen_bad_aux (const char *line, const DATASET *dset,
3024 			   int *pci)
3025 {
3026     int n = gretl_namechar_spn(line);
3027     char word[FN_NAMELEN];
3028     int ci, err = E_DATA;
3029 
3030     *word = '\0';
3031 
3032     if (n > 0) {
3033 	if (n > FN_NAMELEN - 1) {
3034 	    n = FN_NAMELEN - 1;
3035 	}
3036 	strncat(word, line, n);
3037     }
3038 
3039     *pci = ci = gretl_command_number(word);
3040 
3041     if (ci == GENR || ci == PRINT || ci == PRINTF || ci == EVAL) {
3042 	err = 0;
3043     } else if (plausible_genr_start(line, dset)) {
3044 	err = 0;
3045     } else if (function_lookup(word)) {
3046 	err = 0;
3047     } else if (get_user_function_by_name(word)) {
3048 	err = 0;
3049     } else if (ci > 0) {
3050 	gretl_errmsg_sprintf(_("command '%s' not valid in this context"),
3051 			     word);
3052     } else {
3053 	gretl_errmsg_sprintf(_("'%s': not valid in this context"),
3054 			     word);
3055     }
3056 
3057     return err;
3058 }
3059 
3060 /* convert printf from command to function form, if needed */
3061 
revise_aux_printf(const char * s)3062 static gchar *revise_aux_printf (const char *s)
3063 {
3064     gchar *tmp = NULL;
3065 
3066     if (!strncmp(s, "printf ", 7)) {
3067 	tmp = g_strdup_printf("printf(%s)", s + 7);
3068     } else {
3069 	tmp = g_strdup(s);
3070     }
3071 
3072     return tmp;
3073 }
3074 
3075 /**
3076  * nlspec_add_aux:
3077  * @spec: pointer to nls specification.
3078  * @s: string specifying an auxiliary command (primarily
3079  * for use in calculating function or derivatives).
3080  * @dset: pointer to dataset information.
3081  *
3082  * Adds the specification of an auxiliary command to @spec,
3083  * which pointer must have previously been obtained by a call
3084  * to nlspec_new().
3085  *
3086  * Returns: 0 on success, non-zero error code on error.
3087  */
3088 
nlspec_add_aux(nlspec * spec,const char * s,const DATASET * dset)3089 int nlspec_add_aux (nlspec *spec, const char *s, const DATASET *dset)
3090 {
3091     int ci, err;
3092 
3093 #if NLS_DEBUG
3094     fprintf(stderr, "nlspec_add_aux: s = '%s'\n", s);
3095 #endif
3096 
3097     err = screen_bad_aux(s, dset, &ci);
3098     if (!err) {
3099 	if (ci == PRINTF) {
3100 	    gchar *tmp = revise_aux_printf(s);
3101 
3102 	    if (tmp != NULL) {
3103 		err = strings_array_add(&spec->aux, &spec->naux, tmp);
3104 		g_free(tmp);
3105 	    }
3106 	} else {
3107 	    err = strings_array_add(&spec->aux, &spec->naux, s);
3108 	}
3109     }
3110 
3111     return err;
3112 }
3113 
3114 /**
3115  * nlspec_set_regression_function:
3116  * @spec: pointer to nls specification.
3117  * @fnstr: string specifying nonlinear regression function.
3118  * @dset: information on dataset.
3119  *
3120  * Adds the regression function to @spec.  This pointer must
3121  * have previously been obtained by a call to nlspec_new().
3122  * The required format for @fnstr is "%varname = %formula", where
3123  * %varname is the name of the dependent variable and %formula
3124  * is an expression of the sort that is fed to gretl's %genr command.
3125  * The dependent variable must be already present in the
3126  * dataset.
3127  *
3128  * Returns: 0 on success, non-zero error code on error.
3129  */
3130 
3131 int
nlspec_set_regression_function(nlspec * spec,const char * fnstr,const DATASET * dset)3132 nlspec_set_regression_function (nlspec *spec, const char *fnstr,
3133 				const DATASET *dset)
3134 {
3135     const char *p = fnstr;
3136     char *vname = NULL;
3137     char *rhs = NULL;
3138     int flen, err = 0;
3139 
3140     if (spec->nlfunc != NULL) {
3141 	free(spec->nlfunc);
3142 	spec->nlfunc = NULL;
3143     }
3144 
3145     spec->dv = 0;
3146 
3147     if (!strncmp(p, "nls ", 4) ||
3148 	!strncmp(p, "mle ", 4) ||
3149 	!strncmp(p, "gmm ", 4)) {
3150 	p += 4;
3151     } else if (!strncmp(p, "gmm", 3)) {
3152 	p += 3;
3153     }
3154 
3155     if (spec->ci == GMM && string_is_blank(p)) {
3156 	/* GMM: we don't insist on a function on the first line */
3157 	return 0;
3158     }
3159 
3160     if (equation_get_lhs_and_rhs(p, &vname, &rhs)) {
3161 	gretl_errmsg_sprintf(_("parse error in '%s'\n"), fnstr);
3162 	err =  E_PARSE;
3163     } else if (spec->ci == NLS) {
3164 	/* the dependent variable must be a series */
3165 	spec->dv = series_index(dset, vname);
3166 	if (spec->dv == dset->v) {
3167 	    gretl_errmsg_sprintf(_("'%s' is not a known series"), vname);
3168 	    err = E_UNKVAR;
3169 	}
3170     } else {
3171 	*spec->lhname = '\0';
3172 	strncat(spec->lhname, vname, VNAMELEN - 1);
3173     }
3174 
3175     if (!err) {
3176 	if (spec->ci == MLE || spec->ci == GMM) {
3177 	    spec->nlfunc = gretl_strdup(rhs);
3178 	} else {
3179 	    flen = strlen(vname) + strlen(rhs) + 6;
3180 	    spec->nlfunc = malloc(flen);
3181 	    if (spec->nlfunc != NULL) {
3182 		/* the equation defining the NLS residual */
3183 		sprintf(spec->nlfunc, "%s - (%s)", vname, rhs);
3184 	    }
3185 	}
3186 
3187 	if (spec->nlfunc == NULL) {
3188 	    err = E_ALLOC;
3189 	}
3190     }
3191 
3192     free(vname);
3193     free(rhs);
3194 
3195     return err;
3196 }
3197 
3198 /**
3199  * nlspec_set_t1_t2:
3200  * @spec: pointer to nls specification.
3201  * @t1: starting observation.
3202  * @t2: ending observation.
3203  *
3204  * Sets the sample range for estimation of @spec.  This pointer must
3205  * have previously been obtained by a call to nlspec_new().
3206  */
3207 
nlspec_set_t1_t2(nlspec * spec,int t1,int t2)3208 void nlspec_set_t1_t2 (nlspec *spec, int t1, int t2)
3209 {
3210     if (spec != NULL) {
3211 	spec->t1 = t1;
3212 	spec->t2 = t2;
3213 	spec->nobs = t2 - t1 + 1;
3214     }
3215 }
3216 
3217 #define parnames_line(s) (!strncmp(s, "param_names ", 12))
3218 
3219 #define param_line(s) (!strncmp(s, "deriv ", 6) || \
3220                        !strncmp(s, "params ", 7) || \
3221                        !strncmp(s, "orthog ", 7) || \
3222                        !strncmp(s, "weights ", 8) || \
3223                        !strncmp(s, "hessian ", 8))
3224 
3225 #define cmd_start(s) (!strncmp(s, "nls ", 4) || \
3226                       !strncmp(s, "mle ", 4) || \
3227                       !strncmp(s, "gmm ", 4) || \
3228                       !strcmp(s, "gmm"))
3229 
3230 /**
3231  * nl_parse_line:
3232  * @ci: %NLS, %MLE or %GMM.
3233  * @line: string containing information to be added to a
3234  * nonlinear model specification.
3235  * @dset: dataset struct.
3236  * @prn: gretl printing struct (for warning messages).
3237  *
3238  * This function is used to create the specification of a
3239  * nonlinear model, to be estimated via #nl_model (i.e.
3240  * via NLS, MLE or GMM).  It can be called several times to
3241  * build up the required information.  See the manual
3242  * entries for nls, mle and gmm for details.
3243  *
3244  * Returns: 0 on success, non-zero error code on failure.
3245  */
3246 
nl_parse_line(int ci,const char * line,const DATASET * dset,PRN * prn)3247 int nl_parse_line (int ci, const char *line,
3248 		   const DATASET *dset, PRN *prn)
3249 {
3250     nlspec *s = &private_spec;
3251     int err = 0;
3252 
3253     s->ci = ci;
3254 
3255 #if NLS_DEBUG
3256     fprintf(stderr, "nls_parse_line: '%s'\n", line);
3257 #endif
3258 
3259     if (cmd_start(line)) {
3260 	if (s->nlfunc != NULL) {
3261 	    clear_nlspec(s);
3262 	}
3263 	err = nlspec_set_regression_function(s, line, dset);
3264 	if (!err) {
3265 	    nlspec_set_t1_t2(s, dset->t1, dset->t2);
3266 	}
3267     } else if (param_line(line)) {
3268 	if (s->nlfunc == NULL && s->ci != GMM) {
3269 	    gretl_errmsg_set(_("No regression function has been specified"));
3270 	    err = E_PARSE;
3271 	} else {
3272 	    if (!strncmp(line, "deriv", 5)) {
3273 		if (numeric_mode(s) && s->params != NULL) {
3274 		    gretl_errmsg_set(_("You cannot supply both a \"params\" "
3275 				       "line and analytical derivatives"));
3276 		    err = E_PARSE;
3277 		} else {
3278 		    err = nlspec_add_param_with_deriv(s, line);
3279 		}
3280 	    } else if (!strncmp(line, "params", 6)) {
3281 		if (numeric_mode(s)) {
3282 		    err = nlspec_add_params_from_line(s, line + 6);
3283 		} else {
3284 		    pprintf(prn, _("Analytical derivatives supplied: "
3285 				   "\"params\" line will be ignored"));
3286 		    pputc(prn, '\n');
3287 		}
3288 	    } else if (!strncmp(line, "orthog", 6)) {
3289 		err = nlspec_add_orthcond(s, line + 6, dset);
3290 	    } else if (!strncmp(line, "weights", 7)) {
3291 		err = nlspec_add_weights(s, line + 7);
3292 	    } else if (!strncmp(line, "hessian", 7)) {
3293 		err = nlspec_add_hessian(s, line + 8);
3294 	    }
3295 	}
3296     } else if (parnames_line(line)) {
3297 	err = nlspec_add_param_names(s, line + 12);
3298     } else {
3299 	err = nlspec_add_aux(s, line, dset);
3300     }
3301 
3302     if (err) {
3303 	/* remember to clean up! */
3304 	clear_nlspec(s);
3305     }
3306 
3307     return err;
3308 }
3309 
nl_set_smallstep(void)3310 int nl_set_smallstep (void)
3311 {
3312     if (private_spec.nlfunc != NULL) {
3313 	private_spec.flags |= NL_SMALLSTEP;
3314 	return 0;
3315     } else {
3316 	return E_DATA;
3317     }
3318 }
3319 
3320 static double default_nls_toler;
3321 
3322 /**
3323  * get_default_nls_toler:
3324  *
3325  * Returns: the default value used in the convergence criterion
3326  * for estimation of models using nonlinear least squares.
3327  */
3328 
get_default_nls_toler(void)3329 double get_default_nls_toler (void)
3330 {
3331     if (default_nls_toler == 0.0) {
3332 	default_nls_toler = pow(DBL_EPSILON, .75);
3333     }
3334 
3335     return default_nls_toler;
3336 }
3337 
check_spec_requirements(nlspec * spec)3338 static int check_spec_requirements (nlspec *spec)
3339 {
3340     int err = 0;
3341 
3342     if (spec->nparam < 1) {
3343 	gretl_errmsg_set(_("No parameters have been specified"));
3344 	err = 1;
3345     } if (spec->ci == GMM) {
3346 	err = check_gmm_requirements(spec);
3347     }
3348 
3349     return err;
3350 }
3351 
3352 /* make any adjustments that may be needed in case the value
3353    returned by the user's likelihood function is a scalar
3354 */
3355 
mle_scalar_check(nlspec * spec)3356 static int mle_scalar_check (nlspec *spec)
3357 {
3358     int err = 0;
3359 
3360     if (scalar_loglik(spec)) {
3361 	/* without per-observation likelihood values, we can do
3362 	   neither OPG nor QML */
3363 	if (spec->opt & OPT_R) {
3364 	    gretl_errmsg_set("Scalar loglikelihood: can't do QML");
3365 	    err = E_BADOPT;
3366 	} else if (!(spec->opt & OPT_A)) {
3367 	    /* ensure that we use the Hessian */
3368 	    spec->opt |= OPT_H;
3369 	}
3370 	if (analytic_mode(spec)) {
3371 	    /* analytic mode: suppress gradient check */
3372 	    spec->opt |= OPT_S;
3373 	}
3374     }
3375 
3376     return err;
3377 }
3378 
nls_run_GNR(MODEL * pmod,nlspec * spec,PRN * prn)3379 static void nls_run_GNR (MODEL *pmod, nlspec *spec, PRN *prn)
3380 {
3381     DATASET *gdset = NULL;
3382     int *glist = NULL;
3383     int perfect = 0;
3384     int err = 0;
3385 
3386     gdset = make_GNR_dataset(spec, spec->dset, &glist, &perfect,
3387 			     prn, &err);
3388 
3389     if (err) {
3390 	pmod->errcode = err;
3391     } else {
3392 	*pmod = GNR(glist, gdset, spec->opt, prn);
3393 	if (pmod->errcode == 0 || pmod->errcode == E_JACOBIAN) {
3394 	    if (pmod->errcode == 0 && (spec->opt & OPT_B)) {
3395 		QLR_test(pmod, gdset, OPT_Q | OPT_M, NULL);
3396 	    }
3397 	    pmod->errcode = finalize_nls_model(pmod, spec,
3398 					       perfect, glist);
3399 	}
3400 	destroy_dataset(gdset);
3401 	free(glist);
3402     }
3403 }
3404 
3405 /* static function providing the real content for the two public
3406    wrapper functions below: does NLS, MLE or GMM */
3407 
real_nl_model(nlspec * spec,DATASET * dset,gretlopt opt,PRN * prn)3408 static MODEL real_nl_model (nlspec *spec, DATASET *dset,
3409 			    gretlopt opt, PRN *prn)
3410 {
3411     MODEL nlmod;
3412     int origv = 0;
3413     int err = 0;
3414 
3415     if (spec == NULL) {
3416 	/* we use the static spec composed via nl_parse_line() */
3417 	spec = &private_spec;
3418     }
3419 
3420     gretl_model_init(&nlmod, dset);
3421 
3422     if (dset != NULL) {
3423 	origv = dset->v;
3424     }
3425 
3426     if (spec->nlfunc == NULL && spec->ci != GMM) {
3427 	gretl_errmsg_set(_("No function has been specified"));
3428 	nlmod.errcode = E_PARSE;
3429 	goto bailout;
3430     }
3431 
3432     spec->opt = opt;
3433 
3434     /* make dset and prn available via spec */
3435     spec->dset = dset;
3436     spec->prn = prn;
3437 
3438     if (spec->opt & OPT_N) {
3439 	/* ignore any analytical derivs */
3440 	set_numeric_mode(spec);
3441     }
3442 
3443     if (numeric_mode(spec) && spec->nparam == 0 && spec->ci != GMM) {
3444 	gretl_errmsg_sprintf(_("%s: no parameters were specified"),
3445 			     gretl_command_word(spec->ci));
3446 	nlmod.errcode = E_DATA;
3447 	goto bailout;
3448     }
3449 
3450     if (check_spec_requirements(spec)) {
3451 	nlmod.errcode = E_PARSE;
3452 	goto bailout;
3453     }
3454 
3455     if (nl_coeff_check(spec)) {
3456 	nlmod.errcode = E_DATA;
3457 	goto bailout;
3458     }
3459 
3460     if (spec->ci == GMM) {
3461 	err = gmm_missval_check_etc(spec);
3462     } else if (dset != NULL) {
3463 	err = nl_missval_check(spec, dset);
3464     }
3465 
3466     if (!err && spec->ci == MLE) {
3467 	err = mle_scalar_check(spec);
3468     }
3469 
3470     if (err) {
3471 	nlmod.errcode = err;
3472 	goto bailout;
3473     }
3474 
3475     if (spec->lhtype == GRETL_TYPE_DOUBLE) {
3476 	spec->fvec = NULL;
3477 	spec->J = NULL;
3478     } else {
3479 	/* allocate auxiliary arrays */
3480 	size_t fvec_bytes = spec->nobs * sizeof *spec->fvec;
3481 
3482 	spec->fvec = malloc(fvec_bytes);
3483 	spec->J = gretl_matrix_alloc(spec->nobs, spec->ncoeff);
3484 
3485 	if (spec->fvec == NULL || spec->J == NULL) {
3486 	    nlmod.errcode = E_ALLOC;
3487 	    goto bailout;
3488 	}
3489 
3490 	if (spec->lvec != NULL) {
3491 	    memcpy(spec->fvec, spec->lvec->val, fvec_bytes);
3492 	} else {
3493 	    /* not scalar or vector: must be a series */
3494 	    if (dset == NULL || dset->v == 0) {
3495 		nlmod.errcode = E_NODATA;
3496 		goto bailout;
3497 	    } else {
3498 		double *src = spec->dset->Z[spec->lhv] + spec->t1;
3499 
3500 		memcpy(spec->fvec, src, fvec_bytes);
3501 	    }
3502 	}
3503     }
3504 
3505     /* get tolerance from user setting or default */
3506     if (spec->ci == MLE || spec->ci == GMM) {
3507 	spec->tol = libset_get_double(BFGS_TOLER);
3508     } else {
3509 	spec->tol = libset_get_double(NLS_TOLER);
3510     }
3511 
3512     if (spec->ci != GMM && !(spec->opt & (OPT_Q | OPT_M))) {
3513 	pputs(prn, (numeric_mode(spec))?
3514 	      _("Using numerical derivatives\n") :
3515 	      _("Using analytical derivatives\n"));
3516     }
3517 
3518     /* now start the actual calculations */
3519 
3520     if (spec->ci == MLE) {
3521 	err = mle_calculate(spec, prn);
3522     } else if (spec->ci == GMM) {
3523 	err = gmm_calculate(spec, prn);
3524 	if (err) {
3525 	    fprintf(stderr, "gmm_calculate returned %d\n", err);
3526 	}
3527     } else {
3528 	/* NLS: invoke the appropriate minpack driver function */
3529 	gretl_iteration_push();
3530 	if (numeric_mode(spec)) {
3531 	    err = lm_approximate(spec, prn);
3532 	} else {
3533 	    err = lm_calculate(spec, prn);
3534 	    if (err) {
3535 		fprintf(stderr, "lm_calculate returned %d\n", err);
3536 	    }
3537 	}
3538 	gretl_iteration_pop();
3539     }
3540 
3541     if (!(spec->opt & (OPT_Q | OPT_M)) && !(spec->flags & NL_NEWTON)) {
3542 	pprintf(prn, _("Tolerance = %g\n"), spec->tol);
3543     }
3544 
3545     if (!err) {
3546 	if (spec->ci == NLS) {
3547 	    if (spec->opt & OPT_C) {
3548 		/* coefficients only: don't bother with GNR */
3549 		add_nls_coeffs(&nlmod, spec);
3550 	    } else {
3551 		/* use Gauss-Newton Regression for covariance matrix,
3552 		   standard errors */
3553 		nls_run_GNR(&nlmod, spec, prn);
3554 	    }
3555 	} else {
3556 	    /* MLE, GMM */
3557 	    make_other_nl_model(&nlmod, spec, dset);
3558 	}
3559     } else if (nlmod.errcode == 0) {
3560 	/* model error code missing */
3561 	nlmod.errcode = err;
3562     }
3563 
3564     /* ensure that the canonical parameter values get back
3565        into external scalars or vectors */
3566     update_coeff_values(spec->coeff, spec);
3567 
3568  bailout:
3569 
3570     if (spec->nvec > 0 && analytic_mode(spec)) {
3571 	destroy_private_matrices();
3572     }
3573 
3574     destroy_private_scalars();
3575     clear_nlspec(spec);
3576 
3577 #if NLS_DEBUG
3578     fprintf(stderr, "real_nl_model: finishing, dropping %d series\n",
3579 	    dset->v - origv);
3580 #endif
3581 
3582     if (dset != NULL && !dset->auxiliary) {
3583 	dataset_drop_last_variables(dset, dset->v - origv);
3584     }
3585 
3586     if (!(opt & OPT_A) && !nlmod.errcode) {
3587 	set_model_id(&nlmod, opt);
3588     }
3589 
3590     return nlmod;
3591 }
3592 
3593 /**
3594  * nl_model:
3595  * @dset: dataset struct.
3596  * @opt: may include %OPT_V for verbose output, %OPT_R
3597  * for robust covariance matrix.
3598  * @prn: printing struct.
3599  *
3600  * Computes estimates of a model via nonlinear least squares,
3601  * maximum likelihood, or GMM.  The model must have been specified
3602  * previously, via calls to the function #nl_parse_line.  Those
3603  * calls determine, among other things, which estimator will
3604  * be used.
3605  *
3606  * Returns: a model struct containing the parameter estimates
3607  * and associated statistics.
3608  */
3609 
nl_model(DATASET * dset,gretlopt opt,PRN * prn)3610 MODEL nl_model (DATASET *dset, gretlopt opt, PRN *prn)
3611 {
3612     return real_nl_model(NULL, dset, opt, prn);
3613 }
3614 
3615 /**
3616  * model_from_nlspec:
3617  * @spec: nonlinear model specification.
3618  * @dset: dataset struct.
3619  * @opt: may include %OPT_V for verbose output, %OPT_A to
3620  * treat as an auxiliary model, %OPT_C to produce coefficient
3621  * estimates only (don't bother with GNR to produce standard
3622  * errors).
3623  * @prn: printing struct.
3624  *
3625  * Computes estimates of the model specified in @spec.
3626  * The @spec must first be obtained using nlspec_new(), and
3627  * initialized using nlspec_set_regression_function().  If analytical
3628  * derivatives are to be used (which is optional but recommended)
3629  * these are set using nlspec_add_param_with_deriv().
3630  *
3631  * Returns: a model struct containing the parameter estimates
3632  * and associated statistics.
3633  */
3634 
model_from_nlspec(nlspec * spec,DATASET * dset,gretlopt opt,PRN * prn)3635 MODEL model_from_nlspec (nlspec *spec, DATASET *dset,
3636 			 gretlopt opt, PRN *prn)
3637 {
3638     return real_nl_model(spec, dset, opt, prn);
3639 }
3640 
3641 /**
3642  * nlspec_new:
3643  * @ci: %NLS, %MLE or %GMM.
3644  * @dset: information on dataset.
3645  *
3646  * Returns: a pointer to a newly allocated nonlinear model
3647  * specification, or NULL on failure.
3648  */
3649 
nlspec_new(int ci,const DATASET * dset)3650 nlspec *nlspec_new (int ci, const DATASET *dset)
3651 {
3652     nlspec *spec;
3653 
3654     spec = malloc(sizeof *spec);
3655     if (spec == NULL) {
3656 	return NULL;
3657     }
3658 
3659     spec->nlfunc = NULL;
3660 
3661     spec->params = NULL;
3662     spec->nparam = 0;
3663 
3664     spec->aux = NULL;
3665     spec->naux = 0;
3666 
3667     spec->genrs = NULL;
3668     spec->ngenrs = 0;
3669     spec->generr = 0;
3670 
3671     spec->hgen = NULL;
3672     spec->hesscall = NULL;
3673 
3674     spec->fvec = NULL;
3675     spec->J = NULL;
3676 
3677     spec->coeff = NULL;
3678     spec->ncoeff = 0;
3679     spec->nvec = 0;
3680 
3681     spec->Hinv = NULL;
3682 
3683     spec->ci = ci;
3684     spec->flags = 0;
3685     spec->opt = OPT_NONE;
3686 
3687     spec->dv = 0;
3688     spec->lhtype = GRETL_TYPE_NONE;
3689     *spec->lhname = '\0';
3690     *spec->hname = '\0';
3691     spec->parnames = NULL;
3692     spec->lhv = 0;
3693     spec->lvec = NULL;
3694 
3695     spec->iters = 0;
3696     spec->fncount = 0;
3697     spec->grcount = 0;
3698 
3699     spec->t1 = spec->real_t1 = dset->t1;
3700     spec->t2 = spec->real_t2 = dset->t2;
3701     spec->nobs = spec->t2 - spec->t1 + 1;
3702 
3703     spec->dset = NULL;
3704     spec->prn = NULL;
3705 
3706     spec->oc = NULL;
3707     spec->missmask = NULL;
3708 
3709     return spec;
3710 }
3711 
3712 /**
3713  * nlspec_destroy:
3714  * @spec: pointer to nls specification.
3715  *
3716  * Frees all resources associated with @spec, and frees the
3717  * pointer itself.
3718  */
3719 
nlspec_destroy(nlspec * spec)3720 void nlspec_destroy (nlspec *spec)
3721 {
3722     clear_nlspec(spec);
3723     free(spec);
3724 }
3725 
3726 /* below: apparatus for estimating a "tsls" model via GMM */
3727 
3728 #define IVREG_RESIDNAME  "_gmm_e"
3729 #define IVREG_WEIGHTNAME "_gmm_V"
3730 
ivreg_nlfunc_setup(nlspec * spec,MODEL * pmod,DATASET * dset)3731 static int ivreg_nlfunc_setup (nlspec *spec, MODEL *pmod,
3732 			       DATASET *dset)
3733 {
3734     PRN *prn;
3735     int v = pmod->list[1];
3736     int k = pmod->ncoeff;
3737     const char *buf;
3738     int i, err = 0;
3739 
3740     prn = gretl_print_new(GRETL_PRINT_BUFFER, &err);
3741     if (err) {
3742 	return err;
3743     }
3744 
3745     pprintf(prn, "gmm %s = %s-(", IVREG_RESIDNAME, dset->varname[v]);
3746     for (i=0; i<k; i++) {
3747 	if (i == 0 && pmod->ifc) {
3748 	    pputs(prn, "_b0");
3749 	} else {
3750 	    v = pmod->list[i+2];
3751 	    pprintf(prn, "+_b%d*%s", i, dset->varname[v]);
3752 	}
3753     }
3754     pputc(prn, ')');
3755 
3756     buf = gretl_print_get_buffer(prn);
3757     err = nlspec_set_regression_function(spec, buf, dset);
3758     gretl_print_destroy(prn);
3759 
3760     return err;
3761 }
3762 
ivreg_oc_setup(nlspec * spec,const int * ilist,MODEL * pmod,DATASET * dset,int * rv)3763 static int ivreg_oc_setup (nlspec *spec, const int *ilist,
3764 			   MODEL *pmod, DATASET *dset,
3765 			   int *rv)
3766 {
3767     int v = dset->v;
3768     int i, err;
3769 
3770     /* add GMM residual */
3771     err = dataset_add_series(dset, 1);
3772 
3773     if (!err) {
3774 	*rv = v;
3775 	strcpy(dset->varname[v], IVREG_RESIDNAME);
3776 	for (i=0; i<dset->n; i++) {
3777 	    dset->Z[v][i] = pmod->uhat[i];
3778 	}
3779 	err = nlspec_add_ivreg_oc(spec, v, ilist, (const double **) dset->Z);
3780     }
3781 
3782     return err;
3783 }
3784 
ivreg_weights_setup(nlspec * spec,const int * ilist,gretlopt opt)3785 static int ivreg_weights_setup (nlspec *spec, const int *ilist,
3786 				gretlopt opt)
3787 {
3788     const char *mname = NULL;
3789     int k = ilist[0];
3790     gretl_matrix *V;
3791     int err;
3792 
3793     if (opt & OPT_H) {
3794 	mname = get_optval_string(IVREG, OPT_H);
3795     }
3796 
3797     if (mname != NULL) {
3798 	/* the user requested a specific weights matrix */
3799 	V = get_matrix_by_name(mname);
3800 	if (V == NULL) {
3801 	    err = E_UNKVAR;
3802 	} else if (V->rows != k || V->cols != k) {
3803 	    err = E_NONCONF;
3804 	} else {
3805 	    err = nlspec_add_weights(spec, mname);
3806 	}
3807     } else {
3808 	/* use generic weights */
3809 	V = gretl_identity_matrix_new(k);
3810 	if (V == NULL) {
3811 	    return E_ALLOC;
3812 	}
3813 	err = private_matrix_add(V, IVREG_WEIGHTNAME);
3814 	if (err) {
3815 	    gretl_matrix_free(V);
3816 	} else {
3817 	    err = nlspec_add_weights(spec, IVREG_WEIGHTNAME);
3818 	}
3819     }
3820 
3821     return err;
3822 }
3823 
ivreg_set_params(nlspec * spec,MODEL * pmod)3824 static int ivreg_set_params (nlspec *spec, MODEL *pmod)
3825 {
3826     int np = pmod->ncoeff;
3827     char **names;
3828     int i, err;
3829 
3830     names = strings_array_new_with_length(np, 8);
3831     if (names == NULL) {
3832 	return E_ALLOC;
3833     }
3834 
3835     for (i=0; i<np; i++) {
3836 	sprintf(names[i], "_b%d", i);
3837     }
3838 
3839     err = aux_nlspec_add_param_list(spec, np, pmod->coeff, names);
3840 
3841     strings_array_free(names, np);
3842 
3843     return err;
3844 }
3845 
finalize_ivreg_model(MODEL * pmod,MODEL * ols,const int * biglist,const int * mlist,int ** ilist,const double ** Z,int rv)3846 static int finalize_ivreg_model (MODEL *pmod, MODEL *ols,
3847 				 const int *biglist,
3848 				 const int *mlist,
3849 				 int **ilist,
3850 				 const double **Z,
3851 				 int rv)
3852 {
3853     int *endolist;
3854     int yno = mlist[1];
3855     int t, err = 0;
3856 
3857     pmod->ci = IVREG;
3858     pmod->opt = OPT_G; /* signal use of GMM */
3859 
3860     /* attach tsls-style list */
3861     pmod->list = gretl_list_copy(biglist);
3862     if (pmod->list == NULL) {
3863 	return E_ALLOC;
3864     }
3865 
3866     /* get dep. var. info from OLS model */
3867     pmod->ybar = ols->ybar;
3868     pmod->sdy = ols->sdy;
3869 
3870     /* steal uhat */
3871     if (pmod->uhat != NULL) {
3872 	free(pmod->uhat);
3873     }
3874     pmod->uhat = ols->uhat;
3875     ols->uhat = NULL;
3876 
3877     /* and yhat */
3878     if (pmod->yhat != NULL) {
3879 	free(pmod->yhat);
3880     }
3881     pmod->yhat = ols->yhat;
3882     ols->yhat = NULL;
3883 
3884     /* insert residuals and fitted */
3885     for (t=pmod->t1; t<=pmod->t2; t++) {
3886 	pmod->uhat[t] = Z[rv][t];
3887 	pmod->yhat[t] = Z[yno][t] - Z[rv][t];
3888     }
3889 
3890     endolist = tsls_make_endolist(mlist, ilist, NULL, &err);
3891 
3892     if (endolist != NULL) {
3893 	gretl_model_set_list_as_data(pmod, "endolist", endolist);
3894     }
3895 
3896     return err;
3897 }
3898 
3899 /* Responds when OPT_L is given to the ivreg() function,
3900    which lives in estimate.c
3901 */
3902 
ivreg_via_gmm(const int * list,DATASET * dset,gretlopt opt)3903 MODEL ivreg_via_gmm (const int *list, DATASET *dset, gretlopt opt)
3904 {
3905     int orig_v = dset->v;
3906     int *mlist = NULL, *ilist = NULL;
3907     nlspec *spec = NULL;
3908     MODEL olsmod, model;
3909     int rv = 0;
3910     int err = 0;
3911 
3912     gretl_model_init(&olsmod, dset);
3913     gretl_model_init(&model, dset);
3914 
3915     err = ivreg_process_lists(list, &mlist, &ilist);
3916 
3917     if (!err) {
3918 	spec = nlspec_new(GMM, dset);
3919 	if (spec == NULL) {
3920 	    err = E_ALLOC;
3921 	}
3922     }
3923 
3924     if (!err) {
3925 	/* OLS baseline and check */
3926 	olsmod = lsq(mlist, dset, OLS, OPT_A | OPT_M | OPT_Z);
3927 	err = olsmod.errcode;
3928     }
3929 
3930     if (!err) {
3931 	/* add the definition of the GMM residual */
3932 	err = ivreg_nlfunc_setup(spec, &olsmod, dset);
3933     }
3934 
3935     if (!err) {
3936 	/* add the orthogonality conditions */
3937 	err = ivreg_oc_setup(spec, ilist, &olsmod, dset, &rv);
3938     }
3939 
3940     if (!err) {
3941 	/* add the weights matrix */
3942 	err = ivreg_weights_setup(spec, ilist, opt);
3943     }
3944 
3945     set_auxiliary_scalars();
3946 
3947     if (!err) {
3948 	/* add the scalar parameters */
3949 	err = ivreg_set_params(spec, &olsmod);
3950     }
3951 
3952     if (!err) {
3953 	/* call the GMM estimation routine */
3954 	model = model_from_nlspec(spec, dset, opt | OPT_G, NULL);
3955     }
3956 
3957     unset_auxiliary_scalars();
3958 
3959     if (err) {
3960 	model.errcode = err;
3961     } else {
3962 	/* turn the output model into an "ivreg" type */
3963 	finalize_ivreg_model(&model, &olsmod, list, mlist, &ilist,
3964 			     (const double **) dset->Z, rv);
3965     }
3966 
3967     nlspec_destroy(spec);
3968     free(mlist);
3969     free(ilist);
3970     clear_model(&olsmod);
3971 
3972     dataset_drop_last_variables(dset, dset->v - orig_v);
3973     user_var_delete_by_name(IVREG_WEIGHTNAME, NULL);
3974 
3975     return model;
3976 }
3977 
3978 /* For forecasting purposes ("fcast" command): in general
3979    it's not enough just to run the genr command that
3980    creates or revises the dependent variable; we may also
3981    have to generate some intermediate quantities. In
3982    nl_model_run_aux_genrs() we retrieve any auxiliary
3983    genrs from @pmod and try running them.
3984 */
3985 
nl_model_run_aux_genrs(const MODEL * pmod,DATASET * dset)3986 int nl_model_run_aux_genrs (const MODEL *pmod,
3987 			    DATASET *dset)
3988 {
3989     char line[MAXLEN];
3990     const char *buf;
3991     int i, j, n_aux = 0;
3992     int err = 0;
3993 
3994     n_aux = gretl_model_get_int(pmod, "nl_naux");
3995     if (n_aux == 0) {
3996 	/* nothing to be done? */
3997 	return 0;
3998     }
3999 
4000     buf = gretl_model_get_data(pmod, "nlinfo");
4001     if (buf == NULL) {
4002 	return E_DATA;
4003     }
4004 
4005     bufgets_init(buf);
4006 
4007     i = j = 0;
4008     while (bufgets(line, sizeof line, buf) && !err) {
4009 	if (*line == '#') {
4010 	    continue;
4011 	}
4012 	if (i > 0 && j < n_aux) {
4013 	    tailstrip(line);
4014 	    err = generate(line, dset, GRETL_TYPE_ANY, OPT_P, NULL);
4015 	    if (err) {
4016 		genr_setup_error(line, err, 1);
4017 	    }
4018 	    j++;
4019 	}
4020 	i++;
4021     }
4022 
4023     bufgets_finalize(buf);
4024 
4025     return err;
4026 }
4027 
4028 /* apparatus for bootstrapping NLS forecast errors */
4029 
4030 /* reconstitute the nlspec based on the information saved in @pmod */
4031 
set_nlspec_from_model(const MODEL * pmod,const DATASET * dset)4032 static int set_nlspec_from_model (const MODEL *pmod,
4033 				  const DATASET *dset)
4034 {
4035     char line[MAXLEN];
4036     const char *buf;
4037     int err = 0;
4038 
4039     buf = gretl_model_get_data(pmod, "nlinfo");
4040     if (buf == NULL) {
4041 	return E_DATA;
4042     }
4043 
4044     bufgets_init(buf);
4045 
4046     while (bufgets(line, sizeof line, buf) && !err) {
4047 	tailstrip(line);
4048 	if (!strcmp(line, "end nls")) {
4049 	    break;
4050 	}
4051 	err = nl_parse_line(NLS, line, dset, NULL);
4052     }
4053 
4054     bufgets_finalize(buf);
4055 
4056     if (err) {
4057 	clear_nlspec(&private_spec);
4058     } else {
4059 	private_spec.opt = pmod->opt;
4060 	if (private_spec.opt & OPT_V) {
4061 	    private_spec.opt ^= OPT_V;
4062 	}
4063     }
4064 
4065     return err;
4066 }
4067 
save_scalar_param(parm * p,double ** px,int * n)4068 static int save_scalar_param (parm *p, double **px, int *n)
4069 {
4070     double x = get_param_scalar(p);
4071     int err = 0;
4072 
4073     if (na(x)) {
4074 	err = E_DATA;
4075     } else {
4076 	double *tmp;
4077 	int k = *n + 1;
4078 
4079 	tmp = realloc(*px, k * sizeof *tmp);
4080 	if (tmp == NULL) {
4081 	    err = E_ALLOC;
4082 	} else {
4083 	    *px = tmp;
4084 	    tmp[*n] = x;
4085 	    *n = k;
4086 	}
4087     }
4088 
4089     return err;
4090 }
4091 
save_vector_param(parm * p,gretl_matrix *** pm,int * n)4092 static int save_vector_param (parm *p, gretl_matrix ***pm,
4093 			      int *n)
4094 {
4095     gretl_matrix *m = get_param_vector(p);
4096     int err = 0;
4097 
4098     if (m == NULL) {
4099 	err = E_DATA;
4100     } else {
4101 	gretl_matrix **tmp;
4102 	int k = *n + 1;
4103 
4104 	tmp = realloc(*pm, k * sizeof *tmp);
4105 	if (tmp == NULL) {
4106 	    err = E_ALLOC;
4107 	} else {
4108 	    *pm = tmp;
4109 	    tmp[*n] = gretl_matrix_copy(m);
4110 	    if (tmp[*n] == NULL) {
4111 		err = E_ALLOC;
4112 	    } else {
4113 		*n = k;
4114 	    }
4115 	}
4116     }
4117 
4118     return err;
4119 }
4120 
4121 /* Given an NLS model @pmod, fill out the forecast error series
4122    @fcerr from @ft1 to @ft2 using the bootstrap, based on
4123    resampling the original residuals. See also forecast.c,
4124    from where this function is called.  Here we concentrate
4125    solely on parameter uncertainty.  At present we do this
4126    only for static forecasts.
4127 */
4128 
nls_boot_calc(const MODEL * pmod,DATASET * dset,int ft1,int ft2,double * fcerr)4129 int nls_boot_calc (const MODEL *pmod, DATASET *dset,
4130 		   int ft1, int ft2, double *fcerr)
4131 {
4132     nlspec *spec;
4133     gretl_matrix *fcmat = NULL;
4134     gretl_matrix **msave = NULL;
4135     double *orig_y = NULL;
4136     double *xsave = NULL;
4137     double *resu = NULL;
4138     int origv = dset->v;
4139     int yno = pmod->list[1];
4140     int iters = 100; /* just testing */
4141     int nx = 0, nm = 0;
4142     int i, ix, im, s, t, fT;
4143     int err = 0;
4144 
4145     /* build the 'private' spec, based on @pmod */
4146     err = set_nlspec_from_model(pmod, dset);
4147     if (err) {
4148 	return err;
4149     }
4150 
4151     spec = &private_spec;
4152 
4153     spec->t1 = spec->real_t1 = pmod->t1;
4154     spec->t2 = spec->real_t2 = pmod->t2;
4155     spec->nobs = spec->t2 - spec->t1 + 1;
4156 
4157     /* back up the original parameter values */
4158     for (i=0; i<spec->nparam && !err; i++) {
4159 	parm *p = &spec->params[i];
4160 
4161 	if (p->type == GRETL_TYPE_DOUBLE) {
4162 	    err = save_scalar_param(p, &xsave, &nx);
4163 	} else {
4164 	    err = save_vector_param(p, &msave, &nm);
4165 	}
4166     }
4167 
4168     if (err) {
4169 	goto bailout;
4170     }
4171 
4172     /* back up the original dependent variable */
4173     orig_y = copyvec(dset->Z[yno], dset->n);
4174 
4175     /* allocate storage for resampled residuals */
4176     resu = malloc(dset->n * sizeof *resu);
4177 
4178     /* allocate forecast matrix */
4179     fT = ft2 - ft1 + 1;
4180     fcmat = gretl_matrix_alloc(iters, fT);
4181 
4182     if (orig_y == NULL || resu == NULL || fcmat == NULL) {
4183 	err = E_ALLOC;
4184 	goto bailout;
4185     }
4186 
4187     /* allocate arrays to be passed to minpack */
4188     spec->fvec = malloc(spec->nobs * sizeof *spec->fvec);
4189     spec->J = gretl_matrix_alloc(spec->nobs, spec->ncoeff);
4190 
4191     if (spec->fvec == NULL || spec->J == NULL) {
4192 	err = E_ALLOC;
4193 	goto bailout;
4194     }
4195 
4196     spec->dset = dset;
4197 
4198     for (i=0; i<iters && !err; i++) {
4199 
4200 	/* resample from pmod->uhat into resu */
4201 	resample_series(pmod->uhat, resu, dset);
4202 
4203 	/* construct y^* = \hat{y} + u^* */
4204 	for (t=spec->t1; t<=spec->t2; t++) {
4205 	    /* FIXME rescale the residuals */
4206 	    dset->Z[yno][t] = pmod->yhat[t] + resu[t];
4207 	}
4208 
4209 #if 0
4210 	for (t=spec->t1; t<=spec->t2; t++) {
4211 	    fprintf(stderr, "%d: y = %g, y* = %g\n",
4212 		    t, orig_y[t], dset->Z[yno][t]);
4213 	}
4214 #endif
4215 
4216 	for (t=spec->t1, s=0; t<=spec->t2; t++, s++) {
4217 	    spec->fvec[s] = resu[s];
4218 	}
4219 
4220 	/* re-estimate the model on the resampled data */
4221 	if (numeric_mode(spec)) {
4222 	    err = lm_approximate(spec, NULL);
4223 	} else {
4224 	    err = lm_calculate(spec, NULL);
4225 	}
4226 
4227 	if (!err) {
4228 	    /* generate and record the forecast (FIXME genr expr?) */
4229 	    err = generate(pmod->depvar, dset, GRETL_TYPE_SERIES,
4230 			   OPT_P, NULL);
4231 	    for (t=ft1, s=0; t<=ft2; t++, s++) {
4232 		gretl_matrix_set(fcmat, i, s, dset->Z[yno][t]);
4233 	    }
4234 	}
4235     }
4236 
4237     if (!err) {
4238 	/* compute and record the standard deviations of the forecasts:
4239 	   should we add the square root of the residual variance here?
4240 	*/
4241 	gretl_matrix *sd;
4242 
4243 #if 0
4244 	gretl_matrix_print(fcmat, "Forecast matrix");
4245 #endif
4246 	sd = gretl_matrix_column_sd(fcmat, &err);
4247 	if (!err) {
4248 	    double cfac = sqrt((double) iters / (iters - 1));
4249 
4250 	    for (t=ft1, s=0; t<=ft2; t++, s++) {
4251 		fcerr[t] = sd->val[s] * cfac;
4252 	    }
4253 	    gretl_matrix_free(sd);
4254 	}
4255     }
4256 
4257     if (spec->nvec > 0 && analytic_mode(spec)) {
4258 	destroy_private_matrices();
4259     }
4260 
4261  bailout:
4262 
4263     /* restore original params from backup */
4264     ix = im = 0;
4265     for (i=0; i<spec->nparam; i++) {
4266 	parm *p = &spec->params[i];
4267 
4268 	if (p->type == GRETL_TYPE_DOUBLE && ix < nx) {
4269 	    if (p->bundle != NULL) {
4270 		gretl_bundle_set_scalar(p->bundle, p->name, xsave[ix]);
4271 	    } else {
4272 		gretl_scalar_set_value(p->name, xsave[ix]);
4273 	    }
4274 	    ix++;
4275 	} else if (im < nm) {
4276 	    gretl_matrix *m0 = get_param_vector(p);
4277 	    gretl_matrix *m1 = msave[im];
4278 	    int k, len = gretl_vector_get_length(m0);
4279 
4280 	    for (k=0; k<len; k++) {
4281 		m0->val[k] = m1->val[k];
4282 	    }
4283 	    gretl_matrix_free(msave[im]);
4284 	    im++;
4285 	}
4286     }
4287 
4288     free(xsave);
4289     free(msave);
4290 
4291     clear_nlspec(spec);
4292 
4293     dataset_drop_last_variables(dset, dset->v - origv);
4294 
4295     /* restore original y */
4296     if (orig_y != NULL) {
4297 	for (t=0; t<dset->n; t++) {
4298 	    dset->Z[yno][t] = orig_y[t];
4299 	}
4300     }
4301 
4302     free(orig_y);
4303     free(resu);
4304     gretl_matrix_free(fcmat);
4305 
4306     return err;
4307 }
4308