/* nag_opt_lsq_covariance (e04ycc) Example Program. * * Copyright 1991 Numerical Algorithms Group. * * Mark 2, 1991. * Mark 7 revised, 2001. * Mark 8 revised, 2004. * */ #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif static void NAG_CALL lsqfun(Integer m, Integer n, const double x[], double fvec[], Nag_Comm *comm); #ifdef __cplusplus } #endif /* Define a user structure template to store data in lsqfun */ struct user { double *y; double *t; }; #define T(I, J) t[(I) *tdt + J] int main(void) { Integer exit_status = 0, i, j, job, m, n, nt, tdj, tdt; NagError fail; Nag_Comm comm; Nag_E04_Opt options; double *cj = 0, *fjac = 0, fsumsq, *fvec = 0, *x = 0; struct user s; INIT_FAIL(fail); s.y = 0; s.t = 0; printf("nag_opt_lsq_covariance (e04ycc) Example Program Results\n"); scanf(" %*[^\n]"); /* Skip heading in data file */ n = 3; m = 15; nt = 3; if (n >= 1 && n <= m) { if (!(fjac = NAG_ALLOC(m*n, double)) || !(fvec = NAG_ALLOC(m, double)) || !(x = NAG_ALLOC(n, double)) || !(cj = NAG_ALLOC(n, double)) || !(s.y = NAG_ALLOC(m, double)) || !(s.t = NAG_ALLOC(m*nt, double))) { printf("Allocation failure\n"); exit_status = -1; goto END; } tdj = n; tdt = nt; } else { printf("Invalid n or m.\n"); exit_status = 1; return exit_status; } /* Read data into structure. * Observations t (j = 0, 1, 2) are held in s->t[i][j] * (i = 0, 1, 2, . . ., 14) */ for (i = 0; i < m; ++i) { scanf("%lf", &s.y[i]); for (j = 0; j < nt; ++j) scanf("%lf", &s.T(i, j)); } /* Set up the starting point */ x[0] = 0.5; x[1] = 1.0; x[2] = 1.5; /* nag_opt_init (e04xxc). * Initialization function for option setting */ nag_opt_init(&options); /* Initialise options structure */ /* Assign address of user defined structure to * comm.p for communication to lsqfun(). */ comm.p = (Pointer)&s; /* nag_opt_lsq_no_deriv (e04fcc). * Unconstrained nonlinear least-squares (no derivatives * required) */ fflush(stdout); nag_opt_lsq_no_deriv(m, n, lsqfun, x, &fsumsq, fvec, fjac, tdj, &options, &comm, &fail); if (fail.code != NE_NOERROR && fail.code != NW_COND_MIN) { printf("Error from nag_opt_lsq_no_deriv (e04fcc).\n%s\n", fail.message); exit_status = 1; goto END; } job = 0; /* nag_opt_lsq_covariance (e04ycc). * Covariance matrix for nonlinear least-squares */ nag_opt_lsq_covariance(job, m, n, fsumsq, cj, &options, &fail); if (fail.code != NE_NOERROR) { printf("Error from nag_opt_lsq_covariance (e04ycc).\n%s\n", fail.message); exit_status = 1; goto END; } printf("\nEstimates of the variances of the sample regression"); printf(" coefficients are:\n"); for (i = 0; i < n; ++i) printf(" %15.5e", cj[i]); printf("\n"); /* Free memory allocated to pointers s and v */ /* nag_opt_free (e04xzc). * Memory freeing function for use with option setting */ nag_opt_free(&options, "all", &fail); if (fail.code != NE_NOERROR) { printf("Error from nag_opt_free (e04xzc).\n%s\n", fail.message); exit_status = 1; goto END; } END: NAG_FREE(fjac); NAG_FREE(fvec); NAG_FREE(x); NAG_FREE(cj); NAG_FREE(s.y); NAG_FREE(s.t); return exit_status; } static void NAG_CALL lsqfun(Integer m, Integer n, const double x[], double fvec[], Nag_Comm *comm) { /* Function to evaluate the residuals. * * The address of the user defined structure is recovered in each call * to lsqfun() from comm->p and the structure used in the calculation * of the residuals. */ Integer i, tdt; struct user *s = (struct user *) comm->p; tdt = n; for (i = 0; i < m; ++i) fvec[i] = x[0] + s->T(i, 0) / (x[1]*s->T(i, 1) + x[2]*s->T(i, 2)) - s->y[i]; } /* lsqfun */