/* nag_opt_bounds_mod_deriv2_comp (e04lbc) Example Program.
*
* Copyright 2024 Numerical Algorithms Group.
*
* Mark 30.1, 2024.
*
*
*/
#include <math.h>
#include <nag.h>
#include <stdio.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
static void NAG_CALL funct(Integer n, const double xc[], double *fc,
double gc[], Nag_Comm *comm);
static void NAG_CALL h(Integer n, const double xc[], double fhesl[],
double fhesd[], Nag_Comm *comm);
#ifdef __cplusplus
}
#endif
int main(void) {
const char *optionsfile = "e04lbce.opt";
static double ruser[2] = {-1.0, -1.0};
Integer exit_status = 0;
Nag_Boolean print;
Integer n = 4;
Nag_Comm comm;
Nag_E04_Opt options;
double *bl = 0, *bu = 0, f, *g = 0, *x = 0;
NagError fail;
INIT_FAIL(fail);
printf("nag_opt_bounds_mod_deriv2_comp (e04lbc) Example Program Results\n");
/* For communication with user-supplied functions: */
comm.user = ruser;
if (n >= 1) {
if (!(x = NAG_ALLOC(n, double)) || !(bl = NAG_ALLOC(n, double)) ||
!(bu = NAG_ALLOC(n, double)) || !(g = NAG_ALLOC(n, double))) {
printf("Allocation failure\n");
exit_status = -1;
goto END;
}
} else {
printf("Invalid n.\n");
exit_status = 1;
return exit_status;
}
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] = -1e6;
bu[2] = 1e6;
bl[3] = 1.0;
bu[3] = 3.0;
/* Set up starting point */
x[0] = 3.0;
x[1] = -1.0;
x[2] = 0.0;
x[3] = 1.0;
print = Nag_TRUE;
/* nag_opt_init (e04xxc).
* Initialization function for option setting
*/
nag_opt_init(&options);
/* nag_opt_read (e04xyc).
* Read options from a text file
*/
fflush(stdout);
nag_opt_read("e04lbc", optionsfile, &options, print, "stdout", &fail);
if (fail.code != NE_NOERROR) {
printf("Error from nag_opt_read (e04xyc).\n%s\n", fail.message);
exit_status = 1;
goto END;
}
/* nag_opt_bounds_mod_deriv2_comp (e04lbc), see above. */
nag_opt_bounds_mod_deriv2_comp(n, funct, h, Nag_Bounds, bl, bu, x, &f, g,
&options, &comm, &fail);
if (fail.code != NE_NOERROR) {
printf("Error or warning from "
"nag_opt_bounds_mod_deriv2_comp (e04lbc).\n%s\n",
fail.message);
if (fail.code != NW_COND_MIN)
exit_status = 1;
}
/* Free memory allocated by nag_opt_bounds_deriv (e04kbc) to pointers hesd,
* hesl and state.
*/
/* 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_bounds_mod_deriv2_comp (e04lbc).\n%s\n",
fail.message);
exit_status = 1;
goto END;
}
END:
NAG_FREE(x);
NAG_FREE(bl);
NAG_FREE(bu);
NAG_FREE(g);
return exit_status;
}
static void NAG_CALL funct(Integer n, const double xc[], double *fc,
double gc[], Nag_Comm *comm) {
/* Function to evaluate objective function and its 1st derivatives. */
double term1, term1_sq;
double term2, term2_sq;
double term3, term3_sq, term3_cu;
double term4, term4_sq, term4_cu;
if (comm->user[0] == -1.0) {
printf("(User-supplied callback funct, first invocation.)\n");
fflush(stdout);
comm->user[0] = 0.0;
}
term1 = xc[0] + 10.0 * xc[1];
term1_sq = term1 * term1;
term2 = xc[2] - xc[3];
term2_sq = term2 * term2;
term3 = xc[1] - 2.0 * xc[2];
term3_sq = term3 * term3;
term3_cu = term3 * term3_sq;
term4 = xc[0] - xc[3];
term4_sq = term4 * term4;
term4_cu = term4_sq * term4;
*fc = term1_sq + 5.0 * term2_sq + term3_sq * term3_sq +
10.0 * term4_sq * term4_sq;
gc[0] = 2.0 * term1 + 40.0 * term4_cu;
gc[1] = 20.0 * term1 + 4.0 * term3_cu;
gc[2] = 10.0 * term2 - 8.0 * term3_cu;
gc[3] = -10.0 * term2 - 40.0 * term4_cu;
}
/* funct */
static void NAG_CALL h(Integer n, const double xc[], double fhesl[],
double fhesd[], Nag_Comm *comm) {
/* Routine to evaluate 2nd derivatives */
double term3_sq;
double term4_sq;
if (comm->user[1] == -1.0) {
printf("(User-supplied callback h, first invocation.)\n");
fflush(stdout);
comm->user[1] = 0.0;
}
term3_sq = (xc[1] - 2.0 * xc[2]) * (xc[1] - 2.0 * xc[2]);
term4_sq = (xc[0] - xc[3]) * (xc[0] - xc[3]);
fhesd[0] = 2.0 + 120.0 * term4_sq;
fhesd[1] = 200.0 + 12.0 * term3_sq;
fhesd[2] = 10.0 + 48.0 * term3_sq;
fhesd[3] = 10.0 + 120.0 * term4_sq;
fhesl[0] = 20.0;
fhesl[1] = 0.0;
fhesl[2] = -24.0 * term3_sq;
fhesl[3] = -120.0 * term4_sq;
fhesl[4] = 0.0;
fhesl[5] = -10.0;
}
/* h */