/* nag_opt_nlp (e04ucc) Example Program. * * Copyright 1996 Numerical Algorithms Group. * * Mark 4, 1996. * Mark 5 revised, 1998. * Mark 7 revised, 2001. * Mark 8 revised, 2004. * */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif static void objfun(Integer n, double x[], double *objf, double objgrd[], Nag_Comm *comm); static void confun(Integer n, Integer ncnlin, Integer needc[], double x[], double conf[], double conjac[], Nag_Comm *comm); static void objfun1(Integer n, double x[], double *objf, double objgrd[], Nag_Comm *comm); static void confun1(Integer n, Integer ncnlin, Integer needc[], double x[], double conf[], double conjac[], Nag_Comm *comm); #ifdef __cplusplus } #endif static int ex1(void); static int ex2(void); static void objfun(Integer n, double x[], double *objf, double objgrd[], Nag_Comm *comm) { /* Routine to evaluate objective function and its 1st derivatives. */ if (comm->flag == 0 || comm->flag == 2) *objf = x[0] * x[3] * (x[0] + x[1] + x[2]) + x[2]; if (comm->flag == 2) { objgrd[0] = x[3] * (2.0*x[0] + x[1] + x[2]); objgrd[1] = x[0] * x[3]; objgrd[2] = x[0] * x[3] + 1.0; objgrd[3] = x[0] * (x[0] + x[1] + x[2]); } } /* objfun */ static void confun(Integer n, Integer ncnlin, Integer needc[], double x[], double conf[], double conjac[], Nag_Comm *comm) { #define CONJAC(I,J) conjac[((I)-1)*n + (J) - 1] Integer i, j; /* Routine to evaluate the nonlinear constraints and * their 1st derivatives. */ /* Function Body */ if (comm->first) { /* First call to confun. Set all Jacobian elements to zero. * Note that this will only work when con_deriv = TRUE * (the default; see Section 4 (confun) and 8.2 (con_deriv)). */ for (j = 1; j <= n; ++j) for (i = 1; i <= ncnlin; ++i) CONJAC(i,j) = 0.0; } if (needc[0] > 0) { if (comm->flag == 0 || comm->flag == 2) conf[0] = x[0] * x[0] + x[1] * x[1] + x[2] * x[2] + x[3] * x[3]; if (comm->flag == 2) { CONJAC(1,1) = x[0] * 2.0; CONJAC(1,2) = x[1] * 2.0; CONJAC(1,3) = x[2] * 2.0; CONJAC(1,4) = x[3] * 2.0; } } if (needc[1] > 0) { if (comm->flag == 0 || comm->flag == 2) conf[1] = x[0] * x[1] * x[2] * x[3]; if (comm->flag == 2) { CONJAC(2,1) = x[1] * x[2] * x[3]; CONJAC(2,2) = x[0] * x[2] * x[3]; CONJAC(2,3) = x[0] * x[1] * x[3]; CONJAC(2,4) = x[0] * x[1] * x[2]; } } } /* confun */ static void objfun1(Integer n, double x[], double *objf, double objgrd[], Nag_Comm *comm) { /* Routine to evaluate objective function and its 1st derivatives. */ if (comm->flag == 0 || comm->flag == 2) *objf = x[0] * x[3] * (x[0] + x[1] + x[2]) + x[2]; /* Note, elements of the objective gradient have not been specified. */ } /* objfun1 */ static void confun1(Integer n, Integer ncnlin, Integer needc[], double x[], double conf[], double conjac[], Nag_Comm *comm) { #define CONJAC(I,J) conjac[((I)-1)*n + (J) - 1] /* Routine to evaluate the nonlinear constraints and * their 1st derivatives. */ /* Function Body */ if (needc[0] > 0) { if (comm->flag == 0 || comm->flag == 2) conf[0] = x[0] * x[0] + x[1] * x[1] + x[2] * x[2] + x[3] * x[3]; if (comm->flag == 2) { CONJAC(1,3) = x[2] * 2.0; /* Note only one constraint gradient has been specified * in the first row of the constraint Jacobian. */ } } if (needc[1] > 0) { if (comm->flag == 0 || comm->flag == 2) conf[1] = x[0] * x[1] * x[2] * x[3]; if (comm->flag == 2) { CONJAC(2,2) = x[0] * x[2] * x[3]; CONJAC(2,3) = x[0] * x[1] * x[3]; /* Note only two constraint gradients have been specified * in the second row of the constraint Jacobian. */ } } } /* confun */ int main(void) { /* Two examples are called, ex1() uses the * default settings to solve a problem while * ex2() solves another problem with some * of the optional parameters set by the user. */ Integer exit_status_ex1=0; Integer exit_status_ex2=0; Vprintf("nag_opt_nlp (e04ucc) Example Program Results\n"); Vscanf(" %*[^\n]"); /* Skip heading in data file */ exit_status_ex1 = ex1(); exit_status_ex2 = ex2(); return exit_status_ex1 == 0 && exit_status_ex2 == 0 ? 0 : 1; } #define A(I,J) a[(I)*tda + J] static int ex1(void) { /* Local variables */ Integer exit_status=0, i, j, n, nclin, ncnlin, tda, totalvars; NagError fail; double *a=0, *bl=0, *bu=0, objf, *objgrd=0, *x=0; INIT_FAIL(fail); Vprintf("\nnag_opt_nlp (e04ucc) example 1: no option setting.\n"); /* Skip heading in data file */ Vscanf(" %*[^\n]"); Vscanf("%ld%ld%ld%*[^\n]", &n, &nclin, &ncnlin); if (n>0 && nclin>=0 && ncnlin>=0) { totalvars = n + nclin + ncnlin; if ( !( x = NAG_ALLOC(n, double)) || !( a = NAG_ALLOC(nclin*n, double)) || !( bl = NAG_ALLOC(totalvars, double)) || !( bu = NAG_ALLOC(totalvars, double)) || !( objgrd = NAG_ALLOC(n, double)) ) { Vprintf("Allocation failure\n"); exit_status = -1; goto END; } tda = n; } else { Vprintf("Invalid n or nclin or ncnlin.\n"); exit_status = 1; return exit_status; } /* Read a, bl, bu and x from data file */ /* Read the matrix of linear constraint coefficients */ if (nclin > 0) { for (i = 0; i < nclin; ++i) for (j = 0; j < n; ++j) Vscanf("%lf", &A(i,j)); } Vscanf("%*[^\n]"); /* Remove remainder of line */ /* Read lower bounds */ for (i = 0; i < n + nclin + ncnlin; ++i) Vscanf("%lf", &bl[i]); Vscanf("%*[^\n]"); /* Read upper bounds */ for (i = 0; i < n + nclin + ncnlin; ++i) Vscanf("%lf", &bu[i]); Vscanf("%*[^\n]"); /* Read the initial point x */ for (i = 0; i < n; ++i) Vscanf("%lf", &x[i]); Vscanf("%*[^\n]"); /* nag_opt_nlp (e04ucc). * Minimization with nonlinear constraints using a * sequential QP method */ nag_opt_nlp(n, nclin, ncnlin, a, tda, bl, bu, objfun, confun, x, &objf, objgrd, E04_DEFAULT, NAGCOMM_NULL, &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_nlp (e04ucc).\n%s\n", fail.message); exit_status = 1; goto END; } END: if (x) NAG_FREE(x); if (a) NAG_FREE(a); if (bl) NAG_FREE(bl); if (bu) NAG_FREE(bu); if (objgrd) NAG_FREE(objgrd); return exit_status; } static int ex2(void) { /* Local variables */ Integer exit_status=0, i, j, n, nclin, ncnlin, tda, totalvars; NagError fail; Nag_E04_Opt options; double *a=0, *bl=0, *bu=0, objf, *objgrd=0, *x=0; INIT_FAIL(fail); Vprintf("\nnag_opt_nlp (e04ucc) example 2: using option setting.\n"); /* Skip heading in data file */ Vscanf(" %*[^\n]"); Vscanf("%ld%ld%ld%*[^\n]", &n, &nclin, &ncnlin); if (n>0 && nclin>=0 && ncnlin>=0) { totalvars = n + nclin + ncnlin; if ( !( x = NAG_ALLOC(n, double)) || !( a = NAG_ALLOC(nclin*n, double)) || !( bl = NAG_ALLOC(totalvars, double)) || !( bu = NAG_ALLOC(totalvars, double)) || !( objgrd = NAG_ALLOC(n, double)) ) { Vprintf("Allocation failure\n"); exit_status = -1; goto END; } tda = n; } else { Vprintf("Invalid n or nclin or ncnlin.\n"); exit_status = 1; return exit_status; } /* Read a, bl, bu and x from data file */ /* Read the matrix of linear constraint coefficients */ if (nclin > 0) { for (i = 0; i < nclin; ++i) for (j = 0; j < n; ++j) Vscanf("%lf", &A(i,j)); } Vscanf("%*[^\n]"); /* Remove remainder of line */ /* Read lower bounds */ for (i = 0; i < n + nclin + ncnlin; ++i) Vscanf("%lf", &bl[i]); Vscanf("%*[^\n]"); /* Read upper bounds */ for (i = 0; i < n + nclin + ncnlin; ++i) Vscanf("%lf", &bu[i]); Vscanf("%*[^\n]"); /* Read the initial point x */ for (i = 0; i < n; ++i) Vscanf("%lf", &x[i]); Vscanf("%*[^\n]"); /* nag_opt_init (e04xxc). * Initialization function for option setting */ nag_opt_init(&options); /* nag_opt_read (e04xyc). * Read options from a text file */ nag_opt_read("e04ucc", "stdin", &options, (Nag_Boolean)Nag_TRUE, "stdout", &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_read (e04xyc).\n%s\n", fail.message); exit_status = 1; goto END; } /* nag_opt_nlp (e04ucc), see above. */ nag_opt_nlp(n, nclin, ncnlin, a, tda, bl, bu, objfun1, confun1, x, &objf, objgrd, &options, NAGCOMM_NULL, &fail); if (fail.code != NE_NOERROR) { Vprintf("Error from nag_opt_nlp (e04ucc).\n%s\n", fail.message); exit_status = 1; } /* 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 (x) NAG_FREE(x); if (a) NAG_FREE(a); if (bl) NAG_FREE(bl); if (bu) NAG_FREE(bu); if (objgrd) NAG_FREE(objgrd); return exit_status; }