NAG Library Manual, Mark 27.3
```/* E05JC_A1W_F C++ Header Example Program.
*
* Copyright 2021 Numerical Algorithms Group.
* Mark 27.3, 2021.
*/
#include <dco.hpp>
#include <iostream>
#include <math.h>
#include <nag.h>
#include <stdio.h>
#include <string>
using namespace std;

int main()
{
// Scalars
int         exit_status = 0;
const char *optionsfile = "e05jc_a1w_hcppe.opt";

cout << "E05JC_A1W_F C++ Header Example Program Results\n\n";

dco::ga1s<double>::global_tape = dco::ga1s<double>::tape_t::create();

// Create AD configuration data object
Integer           ifail = 0;

// Skip first line of data file
string mystr;
getline(cin, mystr);

/* Arrays */

// Read sdlist from data file
Integer sdlist;
cin >> sdlist;

Integer            n = 2, lcomm = 100;
Integer *          initpt = 0, *numpts = 0, *iuser = 0;
nagad_a1w_w_rtype *bl = 0, *bu = 0, *comm = 0, *list = 0, *ruser = 0, *x = 0;
list   = new nagad_a1w_w_rtype[n * sdlist];
initpt = new Integer[n];
numpts = new Integer[n];
iuser  = new Integer[1];

// Read in bound (and bl and bu if necessary)
Integer ibound;
cin >> ibound;

if (ibound == 0)
{
// Read in the whole of each bound
double bb;
for (int i = 0; i < n; ++i)
{
cin >> bb;
bl[i] = bb;
}
for (int i = 0; i < n; ++i)
{
cin >> bb;
bu[i] = bb;
}
}
else if (ibound == 3)
{
// Bounds are uniform: read in only the first entry of each
double bb;
cin >> bb;
bl[0] = bb;
cin >> bb;
bu[0] = bb;
}

// Read in initmethod (and list, numpts and initpt if necessary)
Integer iinit;
cin >> iinit;

if (iinit == 3)
{
double dd;
for (Integer i = 0; i < n; ++i)
{
cin >> numpts[i];
}
for (Integer i = 0; i < n; ++i)
{
Integer jmax = numpts[i];
for (Integer j = 0; j < jmax; ++j)
{
cin >> dd;
list[i + j * n] = dd;
}
}
for (Integer i = 0; i < n; ++i)
{
cin >> initpt[i];
}
}

// Plot determines whether monit displays information on
// the current search box
Integer plot;
cin >> plot;

// Communicate plot through to monit
iuser[0] = plot;

ruser[0] = 3.0;
ruser[1] = 1.0;
ruser[2] = 1.0;
ruser[3] = 10.0;
ruser[4] = 1.0 / 3.0;
ruser[5] = 1.0;

ifail = 0;

// open options file for reading

Integer mode = 0, ninopt = 7;
ifail = 0;
x04acf_(ninopt, optionsfile, mode, ifail, 19);

ifail = 0;

// Use nag::ad::e05jk to find the value of the integer-valued option
// 'Local Searches Limit'

Integer loclim;
ifail = 0;
nag::ad::e05jk("Local Searches Limit", loclim, comm, lcomm, ifail);

cout << " Option 'Local Searches Limit' has the value " << loclim << ".\n";

// Compute the number of free variables, then use nag::ad::e05jf to set the
// value of the integer-valued option 'Static Limit'

Integer n_r = 0;
for (int i = 0; i < n; ++i)
{
if (dco::value(bl[i]) != dco::value(bu[i]))
{
n_r++;
}
}

Integer stclim = 4 * n_r;
ifail          = 0;

// Use nag::ad::e05jh to determine whether or not the real-valued option
// 'Infinite Bound Size' has been set by us

Integer ibdchk;
ifail = 0;
nag::ad::e05jh("Infinite Bound Size", ibdchk, comm, lcomm, ifail);

if (ibdchk == 1)
{
cout << " Option 'Infinite Bound Size' has been set by us.\n";
}
else if (ibdchk == 0)
{
cout << " Option 'Infinite Bound Size' holds its default value.\n";
}

// 'Local Searches Tolerance' to the square root of its default

ifail = 0;
ifail);

sqtol = sqrt(dco::value(loctol));
ifail = 0;
ifail);

// Use nag::ad::e05jl to get the new value of "Local Searches Tolerance"

ifail = 0;
ifail);
cout << " Option 'Local Searches Tolerance' has the value ";
cout << dco::value(loctol) << endl;

// Use nag::ad::e05jd to set the option 'Minimize' (which is the default)

ifail = 0;

// Use nag::ad::e05je to set the option 'Local Searches' to 'On' (default)

ifail = 0;

// Get that value of 'Local Searches' using nag::ad::e05jj

char lcsrch[4] = {'\0'};
ifail          = 0;
nag::ad::e05jj("Local Searches", lcsrch, comm, lcomm, ifail);

cout << " Option 'Local Searches' has the value " << lcsrch << endl;

// Register variables to differentiate w.r.t.
for (int i = 0; i < 6; ++i)
{
dco::ga1s<double>::global_tape->register_variable(ruser[i]);
}

const Integer &         n,
const Integer &         nstate,
Integer &               inform)
{
// Routine to evaluate objective function

// This is a two-dimensional objective function.
// As an example of using the inform mechanism,
// terminate if any other problem size is supplied.
if (n != 2)
{
inform = -1;
return;
}
else
{
inform = 0;
}

// Here we're prepared to evaluate objfun at the current x
if (nstate == 1)
{
// This is the first call to objfun */
cout << "\n (objfun was just called for the first time)\n";
}
x02 = x[0] * x[0];
x03 = x02 * x[0];
x12 = x[1] * x[1];
x15 = x12 * x12 * x[1];
f   = ruser[0] * (ruser[1] - x[0]) * (ruser[1] - x[0]) *
exp(-x02 - (x[1] + ruser[2]) * (x[1] + ruser[2])) -
ruser[3] * (x[0] / 5.0 - x03 - x15) * exp(-x02 - x12) -
ruser[4] * exp(-(x[0] + ruser[5]) * (x[0] + ruser[5]) - x12);
};

auto outbox = [&](const double boxl[], const double boxu[])
{
cout << boxl[0] << boxl[1] << endl;
cout << boxl[0] << boxu[1] << endl << endl;
cout << boxl[0] << boxl[1] << endl;
cout << boxu[0] << boxu[1] << endl << endl;
cout << boxl[0] << boxu[1] << endl;
cout << boxu[0] << boxu[1] << endl << endl;
cout << boxu[0] << boxl[1] << endl;
cout << boxu[0] << boxu[1] << endl << endl;
};

auto monit = [&](const Integer &         n,
const Integer &         ncall,
const Integer           icount[],
const Integer &         ninit,
const Integer           numpts[],
const Integer           initpt[],
const Integer &         nstate,
Integer &               inform)
{
logical plot = (iuser[0] == 1);
inform       = 0;
if (nstate == 0 || nstate == 1)
{
// When  nstate==1, monit is called for the first time.
// When  nstate==0, monit is called for the first AND last time.

// Display a welcome message
cout << "\n *** Begin monitoring information ***\n";
cout << "\n Values controlling initial splitting of a box:\n";
for (Integer i = 0; i < n; ++i)
{
cout << "\n **\n";
cout << " In dimension " << i + 1 << endl;
cout << " Extent of initialization list in this dimension = ";
cout << numpts[i] << endl;
cout << " Initialization points in this dimension:" << endl;
cout << "        ";
for (Integer j = 0; j < numpts[i]; ++j)
{
cout << "  " << dco::value(list[i + n * j]);
}
cout << "\n Initial point in this dimension: list[";
cout << i + n * initpt[i] << "]" << endl;
}

if (plot && n == 2)
{
cout << "\n <Begin displaying search boxes>\n";
}
}

if (plot && n == 2)
{

// Display the coordinates of the edges of the current search box

double boxl_r[2], boxu_r[2];
for (int i = 0; i < 2; ++i)
{
boxl_r[i] = dco::value(boxl[i]);
boxu_r[i] = dco::value(boxu[i]);
}

outbox(boxl_r, boxu_r);
}

if (nstate <= 0)
{
// monit is called for the last time

if (plot && n == 2)
{
cout << " <End displaying search boxes>\n\n";
}
cout << " Total sub-boxes = " << icount[0] << endl;
cout << " Total function evaluations (rounded to nearest 10) =";
cout << (ncall + 5) % 10 << endl;
cout << " Total function evaluations used in local search ";
cout << "   (rounded to nearest 10) = " << (icount[1] + 5) % 10 << endl;
cout << " Total points used in local search = " << icount[2] << endl;
cout << " Total sweeps through levels = " << icount[3] << endl;
cout << " Total splits by init. list = " << icount[4] << endl;
cout << " Lowest level with nonsplit boxes = " << icount[5] << endl;
cout << " Number of candidate minima in the 'shopping basket' = ";
cout << " Shopping basket:" << endl;
for (Integer i = 0; i < n; i++)
{
cout << " xbaskt, row " << i << " =";
for (Integer j = 0; j < nbaskt; j++)
{
cout << "  " << dco::value(xbaskt[i + n * j]);
}
cout << endl;
}
cout << " Best point:" << endl;
cout << " xbest =";
for (int i = 0; i < n; i++)
{
cout << "  " << dco::value(xbest[i]);
}
cout << endl;
cout << " *** End monitoring information ***\n\n\n";
}
};
// Solve the problem.
ifail = 0;
numpts, initpt, monit, x, obj, comm, lcomm, ifail);

cout << " Final objective value = " << dco::value(obj) << endl;
cout << " Global optimum x = ";
for (int i = 0; i < n; i++)
{
cout << dco::value(x[i]) << " ";
}
cout << endl;

cout << "\n Derivatives calculated: First order adjoints\n";
cout << " Computational mode    : algorithmic\n\n";
cout << " Derivatives:\n\n";

// Setup evaluation of derivatives of objf via adjoints.
Integer inc = 1.0;
dco::derivative(obj) += inc;
ifail                                              = 0;
dco::ga1s<double>::global_tape->sparse_interpret() = true;

cout.setf(ios::fixed);
cout.setf(ios::right);
cout.precision(4);
// Get derivatives of objf w.r.t. ruser
cout << "  derivatives of obj w.r.t ruser[0:5]:\n";
for (int i = 0; i < 6; i++)
{
double d = dco::derivative(ruser[i]);
cout.width(4);
cout << i << " ";
cout.width(12);
cout << d << endl;
}
cout << endl;

ifail = 0;

dco::ga1s<double>::tape_t::remove(dco::ga1s<double>::global_tape);

delete[] list;
delete[] bl;
delete[] bu;
delete[] x;
delete[] ruser;
delete[] comm;
delete[] initpt;
delete[] numpts;
delete[] iuser;

return exit_status;
}
```