```/* nag_opt_bounds_no_deriv (e04jbc) Example Program.
*
* Copyright 2014 Numerical Algorithms Group.
*
* Mark 2, 1991.
* Mark 7 revised, 2001.
* Mark 8 revised, 2004.
*
*/

#include <nag.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <nag_stdlib.h>
#include <nage04.h>
#include <nagx02.h>

#ifdef __cplusplus
extern "C" {
#endif
static void NAG_CALL objfun(Integer n, const double x[], double *f,
double g[], Nag_Comm *comm);
#ifdef __cplusplus
}
#endif

int main(void)
{
const char    *optionsfile = "e04jbce.opt";
static double ruser[1] = {-1.0};
Integer       exit_status = 0;
Nag_Boolean   print;
Integer       n;
Nag_BoundType bound;
Nag_E04_Opt   options;
double        *bl = 0, *bu = 0, *g = 0, objf, *x = 0;
Nag_Comm      comm;
NagError      fail;

INIT_FAIL(fail);

printf("nag_opt_bounds_no_deriv (e04jbc) Example Program Results\n");

/* For communication with user-supplied functions: */
comm.user = ruser;

fflush(stdout);

n = 4;
if (n >= 1)
{
if (!(x = NAG_ALLOC(n, double)) ||
!(g = NAG_ALLOC(n, double)) ||
!(bl = NAG_ALLOC(n, double)) ||
!(bu = NAG_ALLOC(n, double)))
{
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
}
else
{
printf("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;

/* Initialise options structure */
/* nag_opt_init (e04xxc).
* Initialization function for option setting
*/
nag_opt_init(&options);
strcpy(options.outfile, "stdout");

/* nag_machine_precision (x02ajc). */
options.optim_tol = 100*sqrt(nag_machine_precision);

/* Read remaining option values from file */
print = Nag_TRUE;
* Read options from a text file
*/
nag_opt_read("e04jbc", optionsfile, &options, print, options.outfile, &fail);
if (fail.code != NE_NOERROR)
{
exit_status = 1;
goto END;
}

/* Set bounds on variables */
bound = Nag_Bounds;
bl[0] = 1.0;
bu[0] = 3.0;
bl[1] = -2.0;
bu[1] = 0.0;
/* x[2] is not bounded, so we set bl[2] to a large negative
* number and bu[2] to a large positive number
*/
bl[2] = -1.0e10;
bu[2] = 1.0e10;
bl[3] = 1.0;
bu[3] = 3.0;

/* Call optimization routine */
/* nag_opt_bounds_no_deriv (e04jbc), see above. */
nag_opt_bounds_no_deriv(n, objfun, bound, bl, bu, x, &objf,
g, &options, &comm, &fail);
if (fail.code != NE_NOERROR)
{
printf("Error/Warning from nag_opt_bounds_no_deriv (e04jbc).\n%s\n",
fail.message);
if (fail.code != NW_COND_MIN)
exit_status = 1;
}

/* Free Nag allocated memory */
/* nag_opt_free (e04xzc).
* Memory freeing function for use with option setting
*/
nag_opt_free(&options, "all", &fail);
if (fail.code != NE_NOERROR)
{
printf("Error from nag_opt_free (e04xzc).\n%s\n", fail.message);
exit_status = 2;
}

END:
NAG_FREE(x);
NAG_FREE(g);
NAG_FREE(bl);
NAG_FREE(bu);

return exit_status;
}

static void NAG_CALL objfun(Integer n, const double x[], double *objf,
double g[], Nag_Comm *comm)
{
/* Routine to evaluate objective function. */

double a, b, c, d, x1, x2, x3, x4;

if (comm->user[0] == -1.0)
{
printf("(User-supplied callback objfun, first invocation.)\n");
fflush(stdout);
comm->user[0] = 0.0;
}

x1 = x[0];
x2 = x[1];
x3 = x[2];
x4 = x[3];

/* Supply a single function value */
a = x1 + 10.0*x2;
b = x3 - x4;
c = x2 - 2.0*x3, c *= c;
d = x1 - x4, d *= d;
*objf = a*a + 5.0*b*b + c*c + 10.0*d*d;
}                               /* objfun */
```