/* 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 #include #ifdef __cplusplus extern "C" { #endif static void NAG_CALL 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(int argc, char *argv[]) { FILE *fpin, *fpout; char *outfile = 0; char *optionsfile = 0; 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); /* Check for command-line IO options */ fpin = nag_example_file_io(argc, argv, "-data", NULL); fpout = nag_example_file_io(argc, argv, "-results", NULL); (void) nag_example_file_io(argc, argv, "-options", &optionsfile); (void) nag_example_file_io(argc, argv, "-nag_write", &outfile); if (!outfile) { outfile = NAG_ALLOC(7, char); strcpy(outfile, "stdout"); } s.y = 0; s.t = 0; fprintf(fpout, "nag_opt_lsq_covariance (e04ycc) Example Program Results\n"); fscanf(fpin, " %*[^\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))) { fprintf(fpout, "Allocation failure\n"); exit_status = -1; goto END; } tdj = n; tdt = nt; } else { fprintf(fpout, "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) { fscanf(fpin, "%lf", &s.y[i]); for (j = 0; j < nt; ++j) fscanf(fpin, "%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 */ strcpy(options.outfile, outfile); /* 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) */ if (strcmp(outfile, "stdout")) fclose(fpout); nag_opt_lsq_no_deriv(m, n, lsqfun, x, &fsumsq, fvec, fjac, tdj, &options, &comm, &fail); if (strcmp(outfile, "stdout")) { fpout = fopen(outfile, "a"); } if (fail.code != NE_NOERROR && fail.code != NW_COND_MIN) { fprintf(fpout, "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 */ if (strcmp(outfile, "stdout")) fclose(fpout); nag_opt_lsq_covariance(job, m, n, fsumsq, cj, &options, &fail); if (strcmp(outfile, "stdout")) { fpout = fopen(outfile, "a"); } if (fail.code != NE_NOERROR) { fprintf(fpout, "Error from nag_opt_lsq_covariance (e04ycc).\n%s\n", fail.message); exit_status = 1; goto END; } fprintf(fpout, "\nEstimates of the variances of the sample regression"); fprintf(fpout, " coefficients are:\n"); for (i = 0; i < n; ++i) fprintf(fpout, " %15.5e", cj[i]); fprintf(fpout, "\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) { fprintf(fpout, "Error from nag_opt_free (e04xzc).\n%s\n", fail.message); exit_status = 1; goto END; } END: if (fpin != stdin) fclose(fpin); if (fpout != stdout) fclose(fpout); 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); if (optionsfile) NAG_FREE(optionsfile); if (outfile) NAG_FREE(outfile); return exit_status; } static void NAG_CALL 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 */