/* 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 E04UCC 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); #else static void objfun(Integer *mode, Integer n, const double x[], double *objf, double objgrd[], Integer nstate, Nag_Comm *comm); static void confun(Integer *mode, Integer ncnlin, Integer n, Integer ldcj, const Integer needc[], const double x[], double conf[], double conjac[], Integer nstate, Nag_Comm *comm); #endif #define A(I,J) a[(I)*tda + J] #define CONJAC(I,J) conjac[((I)-1)*n + (J) - 1] int main(void) { /* Local variables */ Integer exit_status=0, i, j, majits, n, nclin, ncnlin, tda, totalvars; double objf, *objgrd=0, *x=0; double *a=0, *bl=0, *bu=0, *ccon=0, *cjac=0, *clamda=0, *hess=0; Integer *istate=0; /*Nag Types*/ Nag_E04State state; NagError fail; Nag_Comm comm; Nag_FileID fileid; INIT_FAIL(fail); Vprintf("\ne04ucc Example Program Results"); n = 4; nclin = 1; ncnlin = 2; 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)) || !(ccon = NAG_ALLOC(ncnlin, double)) || !(cjac = NAG_ALLOC(ncnlin*n, double)) || !(clamda = NAG_ALLOC(totalvars, double)) || !(objgrd = NAG_ALLOC(n, double)) || !(hess = NAG_ALLOC(n*n, double)) || !(istate = NAG_ALLOC(totalvars, Integer)) ) { 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; } /* The matrix of linear constraint coefficients */ if (nclin > 0) { for (i = 0; i < nclin; ++i) for (j = 0; j < n; ++j) A(i,j) = 1.0; } /* Lower bounds */ bl[0] = 1.0; bl[1] = 1.0; bl[2] = 1.0; bl[3] = 1.0; bl[4] = -1.0E+25; bl[5] = -1.0E+25; bl[6] = 25.0; /* Uppper bounds */ bu[0] = 5.0; bu[1] = 5.0; bu[2] = 5.0; bu[3] = 5.0; bu[4] = 20.0; bu[5] = 40.0; bu[6] = 1.0E+25; /* The initial point x */ x[0] = 1.0; x[1] = 5.0; x[2] = 5.0; x[3] = 1.0; #ifdef E04UCC e04ucc(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 e04ucc.\n%s\n", fail.message); exit_status = 1; goto END; } #else /* Call e04wcc to initialise e04wdc. */ e04wcc(&state, &fail); if (fail.code != NE_NOERROR) { Vprintf("Initialisation of e04wcc failed.\n"); exit_status = 1; goto END; } /* By default e04wdc does not print monitoring */ /* information. Call x04acc to set the print file fileid */ x04acc("", 2, &fileid, &fail); if (fail.code != NE_NOERROR) { Vprintf("Fileid could not be obtained.\n"); exit_status = 1; goto END; } e04wgc("Print file", fileid, &state, &fail); /* Solve the problem. */ e04wdc(n, nclin, ncnlin, n, n, n, a, bl, bu, confun, objfun, &majits, istate, ccon, cjac, clamda, &objf, objgrd, hess, x, &state, &comm, &fail); if (fail.code == NE_NOERROR) { Vprintf("\n\nFinal objective value = %11.3f\n", objf); Vprintf("Optimal X = "); for (i = 1; i <= n; ++i) { Vprintf("%9.2f%s", x[i - 1], i%7 == 0 || i == n ?"\n":" "); } } else { Vprintf ("Error message from e04wdc %s\n", fail.message); } #endif END: if (x) NAG_FREE(x); if (a) NAG_FREE(a); if (bl) NAG_FREE(bl); if (bu) NAG_FREE(bu); if (ccon) NAG_FREE(ccon); if (cjac) NAG_FREE(cjac); if (clamda) NAG_FREE(clamda); if (objgrd) NAG_FREE(objgrd); if (hess) NAG_FREE(hess); if (istate) NAG_FREE(istate); return exit_status; } #ifdef E04UCC static void objfun(Integer n, double x[], double *objf, double objgrd[], Nag_Comm *comm) #else static void objfun(Integer *mode, Integer n, const double x[], double *objf, double objgrd[], Integer nstate, Nag_Comm *comm) #endif { /* Routine to evaluate objective function and its 1st derivatives. */ #ifdef E04UCC if (comm->flag == 0 || comm->flag == 2) #else if (*mode == 0 || *mode == 2) #endif *objf = x[0] * x[3] * (x[0] + x[1] + x[2]) + x[2]; #ifdef E04UCC if (comm->flag == 2) #else if (*mode == 1 || *mode == 2) #endif { 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 */ #ifdef E04UCC static void confun(Integer n, Integer ncnlin, Integer needc[], double x[], double conf[], double conjac[], Nag_Comm *comm) #else static void confun(Integer *mode, Integer ncnlin, Integer n, Integer ldcj, const Integer needc[], const double x[], double conf[], double conjac[], Integer nstate, Nag_Comm *comm) #endif { Integer i, j; /* Routine to evaluate the nonlinear constraints and * their 1st derivatives. */ /* Function Body */ #ifdef E04UCC if (comm->first) #else if (nstate == 1) #endif { /* 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) { #ifdef E04UCC if (comm->flag == 0 || comm->flag == 2) #else if (*mode == 0 || *mode == 2) #endif conf[0] = x[0] * x[0] + x[1] * x[1] + x[2] * x[2] + x[3] * x[3]; #ifdef E04UCC if (comm->flag == 2) #else if (*mode == 2) #endif { 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) { #ifdef E04UCC if (comm->flag == 0 || comm->flag == 2) #else if (*mode == 0 || *mode == 2) #endif conf[1] = x[0] * x[1] * x[2] * x[3]; #ifdef E04UCC if (comm->flag == 2) #else if (*mode == 2) #endif { 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 */