/* 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 #ifdef __cplusplus extern "C" { #endif static void lsqfun(Integer m, Integer n, 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; Vprintf("nag_opt_lsq_covariance (e04ycc) Example Program Results.\n"); Vscanf(" %*[^\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)) ) { Vprintf("Allocation failure\n"); exit_status = -1; goto END; } tdj = n; tdt = nt; } else { Vprintf("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) { Vscanf("%lf", &s.y[i]); for (j = 0; j < nt; ++j) Vscanf("%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) */ 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) { Vprintf("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) { Vprintf("Error from nag_opt_lsq_covariance (e04ycc).\n%s\n", fail.message); exit_status = 1; goto END; } Vprintf("\nEstimates of the variances of the sample regression"); Vprintf(" coefficients are:\n"); for (i = 0; i < n; ++i) Vprintf(" %15.5e", cj[i]); Vprintf("\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) { Vprintf("Error from nag_opt_free (e04xzc).\n%s\n", fail.message); exit_status = 1; goto END; } END: if (fjac) NAG_FREE(fjac); if (fvec) NAG_FREE(fvec); if (x) NAG_FREE(x); if (cj) NAG_FREE(cj); if (s.y) NAG_FREE(s.y); if (s.t) NAG_FREE(s.t); return exit_status; } static void lsqfun(Integer m, Integer n, 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 */