/* nag_opt_nlp_revcomm (e04ufc) Example Program.
*
* Copyright 2014 Numerical Algorithms Group.
*
* Mark 23, 2011.
*
*/
#include <stdio.h>
#include <nag.h>
#include <nag_stdlib.h>
#include <nage04.h>
int main(void)
{
/* Scalars */
double objf, nctotal;
Integer exit_status=0, i, irevcm, iter, j, n, nclin, ncnln;
Integer tda, tdcj, tdr, liwork, lwork;
/* Arrays */
double *a=0, *bl=0, *bu=0, *c=0, *cjac=0, *clamda=0, *objgrd=0;
double *r=0, *work=0, rwsav[475], *x=0;
Nag_Boolean lwsav[120];
Integer *iwork=0, *istate=0, iwsav[610], *needc = 0;
char cwsav[5*80];
/* Nag Types */
NagError fail;
#define A(I,J) a[(I-1)*tda + J - 1]
#define CJAC(I,J) cjac[(I-1)*tdcj + J - 1]
INIT_FAIL(fail);
printf("nag_opt_nlp_revcomm (e04ufc) Example Program Results\n");
fflush(stdout);
/* Skip heading in data file */
scanf("%*[^\n]");
scanf("%ld%ld%ld%*[^\n] ", &n, &nclin, &ncnln);
if (n <= 0 || nclin < 0 || ncnln < 0)
{
printf("At least one of n, nclin, or ncnln is invalid\n");
exit_status = 1;
}
else
{
tda = MAX(nclin,n);
tdcj = MAX(ncnln,n);
tdr = n;
nctotal = n + nclin + ncnln;
liwork = 3*n + nclin + 2*ncnln;
lwork = 21*n + 2;
if (ncnln || nclin) lwork += 2*n*n + 11*nclin;
if (ncnln) lwork += n*nclin + 2*n*ncnln + 22*ncnln - 1;
/* Allocate memory */
if (!(a = NAG_ALLOC(tda*MAX(1,nclin), double)) ||
!(bl = NAG_ALLOC(nctotal, double)) ||
!(bu = NAG_ALLOC(nctotal, double)) ||
!(istate = NAG_ALLOC(nctotal, Integer)) ||
!(c = NAG_ALLOC(ncnln, double)) ||
!(cjac = NAG_ALLOC(tdcj*MAX(1,ncnln), double)) ||
!(clamda = NAG_ALLOC(nctotal, double)) ||
!(objgrd = NAG_ALLOC(n, double)) ||
!(r = NAG_ALLOC(tdr*n, double)) ||
!(x = NAG_ALLOC(n, double)) ||
!(needc = NAG_ALLOC(ncnln, Integer)) ||
!(iwork = NAG_ALLOC(liwork, Integer)) ||
!(work = NAG_ALLOC(lwork, double)))
{
printf("Allocation failure\n");
exit_status = -1;
}
else
{
/* Read A, BL, BU and X from data file */
if (nclin > 0)
{
for (i = 1; i <= nclin; ++i)
for (j = 1; j <= n; ++j)
scanf("%lf", &A(i, j));
scanf("%*[^\n] ");
}
for (i = 0; i < nctotal; ++i)
scanf("%lf", &bl[i]);
scanf("%*[^\n] ");
for (i = 0; i < nctotal; ++i)
scanf("%lf", &bu[i]);
scanf("%*[^\n] ");
for (i = 0; i < n; ++i) {
scanf("%lf", &x[i]);
}
/* Set all constraint Jacobian elements to zero.
Note that this will only work when 'Derivative Level = 3'
(the default; see Section 11.2) */
for (j = 1; j <= n; ++j)
for (i = 1; i <= ncnln; ++i)
CJAC(i,j) = 0.0;
/* Initialise nag_opt_nlp_revcomm (e04ufc) */
nag_opt_nlp_revcomm_init("e04ufc",cwsav,5,lwsav,120,iwsav,610,
rwsav,475,&fail);
/* Set print level */
nag_opt_nlp_revcomm_option_set_string("Print Level = 10",lwsav,iwsav,
rwsav,&fail);
/* Solve the problem */
irevcm = 0;
do
{
/* nag_opt_nlp_revcomm (e04ufc).
* Solves the nonlinear programming (NP) problem using
* reverse communication for evaluation of functions.
*/
nag_opt_nlp_revcomm(&irevcm,n,nclin,ncnln,tda,tdcj,tdr,a,bl,bu,
&iter,istate,c,cjac,clamda,&objf,objgrd,r,x,
needc,iwork,liwork,work,lwork,cwsav,lwsav,
iwsav,rwsav,&fail);
if (irevcm == 1 || irevcm == 3)
/* Evaluate the objective function */
objf = x[0]*x[3]*(x[0]+x[1]+x[2]) + x[2];
if (irevcm == 2 || irevcm == 3)
{
/* Evaluate the objective gradient */
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]);
}
if (irevcm == 4 || irevcm == 6)
{
/* Evaluate the nonlinear constraint functions */
if (needc[0] > 0)
c[0] = x[0]*x[0] + x[1]*x[1] + x[2]*x[2] + x[3]*x[3];
if (needc[1] > 0)
c[1] = x[0]*x[1]*x[2]*x[3];
}
if (irevcm == 5 || irevcm == 6)
{
/* Evaluate the constraint Jacobian */
if (needc[0] > 0)
{
CJAC(1,1) = 2.0*x[0];
CJAC(1,2) = 2.0*x[1];
CJAC(1,3) = 2.0*x[2];
CJAC(1,4) = 2.0*x[3];
}
if (needc[1] > 0)
{
CJAC(2,1) = x[1]*x[2]*x[3];
CJAC(2,2) = x[0]*x[2]*x[3];
CJAC(2,3) = x[0]*x[1]*x[3];
CJAC(2,4) = x[0]*x[1]*x[2];
}
}
} while (irevcm > 0);
if (fail.code != NE_NOERROR)
{
printf("nag_opt_nlp_revcomm (e04ufc) failed.\n%s\n",fail.message);
exit_status = 1;
}
}
/* Deallocate any allocated arrays */
NAG_FREE(a);
NAG_FREE(bl);
NAG_FREE(bu);
NAG_FREE(istate);
NAG_FREE(c);
NAG_FREE(cjac);
NAG_FREE(clamda);
NAG_FREE(objgrd);
NAG_FREE(r);
NAG_FREE(x);
NAG_FREE(needc);
NAG_FREE(iwork);
NAG_FREE(work);
}
return exit_status;
}