/* nag_opt_estimate_deriv (e04xac) Example Program. * * Copyright 1998 Numerical Algorithms Group. * * Mark 5, 1998. * Mark 7 revised, 2001. * Mark 8 revised, 2004. * */ #include #include #include #include static int ex1(void); static int ex2(void); #ifdef __cplusplus extern "C" { #endif static void objfun(Integer n, double x[], double *objf, double g[], Nag_Comm *comm); #ifdef __cplusplus } #endif static void objfun(Integer n, double x[], double *objf, double g[], Nag_Comm *comm) { double a, asq, b, bsq, c, csq, d, dsq; a = x[0] + 10.0*x[1]; b = x[2] - x[3]; c = x[1] - 2.0*x[2]; d = x[0] - x[3]; asq = a*a; bsq = b*b; csq = c*c; dsq = d*d; *objf = asq + 5.0*bsq + csq*csq + 10.0*dsq*dsq; if (comm->flag == 2) { g[0] = 2.0*a + 40.0*d*dsq; g[1] = 20.0*a + 4.0*c*csq; g[2] = 10.0*b - 8.0*c*csq; g[3] = -10.0*b - 40.0*d*dsq; } } /* objfun */ int main(void) { Integer exit_status_ex1=0; Integer exit_status_ex2=0; Vprintf("nag_opt_estimate_deriv (e04xac) Example Program Results\n"); exit_status_ex1 = ex1(); exit_status_ex2 = ex2(); return exit_status_ex1 == 0 && exit_status_ex2 == 0 ? 0 : 1; } #define H(I,J) h[(I)*tdh + J] static int ex1(void) { #define MAXN 4 /* Local variables */ Integer exit_status=0, n, tdh; NagError fail; Nag_DerivInfo *deriv_info=0; double *g=0, *h=0, objf, *x=0; INIT_FAIL(fail); n = MAXN; if (n>=1) { if ( !( x = NAG_ALLOC(n, double)) || !( g = NAG_ALLOC(n, double)) || !( h = NAG_ALLOC(n*n, double)) || !( deriv_info = NAG_ALLOC(n, Nag_DerivInfo)) ) { Vprintf("Allocation failure\n"); exit_status = -1; goto END; } tdh = n; } else { Vprintf("Invalid n.\n"); exit_status = 1; return exit_status; } Vprintf("\nExample 1: default options\n"); x[0] = 3.0; x[1] = -1.0; x[2] = 0.0; x[3] = 1.0; /* Pass null pointers for the h_central and h_forward parameters * as we do not need these values. */ /* nag_opt_estimate_deriv (e04xac). * Computes an approximation to the gradient vector and/or * the Hessian matrix for use with nag_opt_nlp (e04ucc) and * other nonlinear optimization functions */ nag_opt_estimate_deriv(n, x, objfun, &objf, g, (double*)0, (double*)0, h, tdh, deriv_info, E04_DEFAULT, NAGCOMM_NULL, &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_estimate_deriv (e04xac).\n%s\n", fail.message); exit_status = 1; goto END; } END: if (x) NAG_FREE(x); if (g) NAG_FREE(g); if (h) NAG_FREE(h); if (deriv_info) NAG_FREE(deriv_info); return exit_status; } /* ex1 */ static int ex2(void) { /* Local variables */ Integer exit_status=0, i, j, n, tdh; double *g=0, *h=0, *h_central=0, *h_forward=0, *hess_diag=0, objf, *x=0; Nag_DerivInfo *deriv_info=0; Nag_E04_Opt options; NagError fail; INIT_FAIL(fail); n = MAXN; if (n>=1) { if ( !( x = NAG_ALLOC(n, double)) || !( h_central = NAG_ALLOC(n, double)) || !( h_forward = NAG_ALLOC(n, double)) || !( g = NAG_ALLOC(n, double)) || !( h = NAG_ALLOC(n*n, double)) || !( hess_diag = NAG_ALLOC(n, double)) || !( deriv_info = NAG_ALLOC(n, Nag_DerivInfo)) ) { Vprintf("Allocation failure\n"); exit_status = -1; goto END; } tdh = n; } else { Vprintf("Invalid n.\n"); exit_status = 1; return exit_status; } x[0] = 3.0; x[1] = -1.0; x[2] = 0.0; x[3] = 1.0; Vprintf("\nExample 2: some options are set\n"); /* nag_opt_init (e04xxc). * Initialization function for option setting */ nag_opt_init(&options); options.list = Nag_FALSE; options.print_deriv = Nag_D_NoPrint; options.deriv_want = Nag_Grad_HessDiag; Vprintf("\nEstimate gradient and Hessian diagonals given function only\n"); /* Note: it is acceptable to pass an array of length n (hess_diag) * as the Hessian parameter in this case. */ /* nag_opt_estimate_deriv (e04xac), see above. */ nag_opt_estimate_deriv(n, x, objfun, &objf, g, h_forward, h_central, hess_diag, tdh, deriv_info, &options, NAGCOMM_NULL, &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_estimate_deriv (e04xac).\n%s\n", fail.message); exit_status = 1; goto END; } Vprintf("\nFunction value: %12.4e\n", objf); Vprintf("Estimated gradient vector\n"); for (i = 0; i < n; ++i) Vprintf("%12.4e ", g[i]); Vprintf("\nEstimated Hessian matrix diagonal\n"); for (i = 0; i < n; ++i) Vprintf("%12.4e ", hess_diag[i]); Vprintf("\n"); options.deriv_want = Nag_HessFull; Vprintf("\nEstimate full Hessian given function and gradients\n"); /* nag_opt_estimate_deriv (e04xac), see above. */ nag_opt_estimate_deriv(n, x, objfun, &objf, g, h_forward, h_central, h, tdh, deriv_info, &options, NAGCOMM_NULL, &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_estimate_deriv (e04xac).\n%s\n", fail.message); exit_status = 1; goto END; } Vprintf("\nFunction value: %12.4e\n", objf); Vprintf("Computed gradient vector\n"); for (i = 0; i < n; ++i) Vprintf("%12.4e ", g[i]); Vprintf("\nEstimated Hessian matrix\n"); for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) Vprintf("%12.4e ", H(i,j)); Vprintf("\n"); } END: if (x) NAG_FREE(x); if (h_central) NAG_FREE(h_central); if (h_forward) NAG_FREE(h_forward); if (g) NAG_FREE(g); if (h) NAG_FREE(h); if (hess_diag) NAG_FREE(hess_diag); if (deriv_info) NAG_FREE(deriv_info); return exit_status; } /* ex2 */