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 = ¶ms[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