Example description
/* X10AA_A1W_F C++ Header Example Program.
 *
 * Copyright 2019 Numerical Algorithms Group.
 * Mark 27, 2019.
 */

#include <nag.h>
#include <nagad.h>
#include <stdio.h>
#include <nag_stdlib.h>
#include <iostream>
using namespace std;

int main(void)
{
  /* Scalars */
  Integer           exit_status = 0, ierr_not_implemented = -199;
  nagad_a1w_w_rtype x, y;
  Integer           ifail, mode;
  double            dydx, dydx_exp, y1, inc;

  /* Arrays */
  void              *ad_handle = 0;

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

  x.value = 0.1;
  x.id = 0;

  cout << "Computing ln(1+x) and its adjoint using s01ba\n\n";

  /*     Create AD tape */
  nagad_a1w_ir_create();

  /*     Create AD configuration data object */
  ifail = 0;
  x10aa_a1w_f_(ad_handle,ifail);

  /*     Set computational mode to nagad_symbolic */
  mode = nagad_symbolic;
  ifail = 0;
  x10ac_a1w_f_(ad_handle,mode,ifail);

  /*     Get and print computational mode */
  /*     Register variables to differentiate w.r.t. */
  ifail = 0;
  x10ad_a1w_f_(ad_handle,mode,ifail);
  if (mode==nagad_symbolic) {
    cout << "Symbolic computational mode is being used\n\n";
  } else if (mode==nagad_algorithmic) {
    cout << "Algorithmic computational mode is being used\n\n";
  }

  /* Try AD computation that expects to use only the algorithmic mode */
  ifail = 1;
  s01ba_a1w_f_(ad_handle,x,y,ifail);
  if (ifail==ierr_not_implemented) {
    cout << "AD computation failed as expected with ifail = " << ifail << "\n\n";
  } else {
    cout << " Unexpected IFAIL returned in AD computation\n";
    cout << "   ifail expected: " << ierr_not_implemented << ifail << "\n";
    cout << "   ifail returned: " << ifail << "\n";
    exit_status = 1;
    goto END;
  }

  /*     Reset computational mode to nagad_algorithmic */
  mode = nagad_algorithmic;
  ifail = 0;
  x10ac_a1w_f_(ad_handle,mode,ifail);
  ifail = 0;
  x10ad_a1w_f_(ad_handle,mode,ifail);
  if (mode==nagad_symbolic) {
    cout << "Symbolic computational mode is being used\n\n";
  } else if (mode==nagad_algorithmic) {
    cout << "Algorithmic computational mode is being used\n\n";
  }

  nagad_a1w_ir_register_variable(&x);

  ifail = 0;
  s01ba_a1w_f_(ad_handle,x,y,ifail);
  y1 = y.value;

  inc = 1.0;
  nagad_a1w_inc_derivative(&y,inc);
  ifail = 0;
  nagad_a1w_ir_interpret_adjoint(ifail);

  /*     Get derivatives */
  dydx = nagad_a1w_get_derivative(x);
  dydx_exp = 1.0/(1.0+x.value);

  cout.setf(ios::scientific,ios::floatfield);
  cout.precision(4);
  cout << "Input value of x             : " << x.value << endl;
  cout << "Output value of ln(1+x)      : " <<  y1 << endl;
  cout << "AD evaluated derivative      : " <<  dydx << endl;
  cout << "Directly computed derivative : " << dydx_exp << endl;

  /*     Remove computational data object and tape */
 END:
  ifail = 0;
  x10ab_a1w_f_(ad_handle,ifail);
  nagad_a1w_ir_remove();
  return exit_status;
}