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

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

int main(void)
{
  // Scalars
  int               exit_status = 0;
  Integer           n = 21;
  double            ar = 1.0;

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

  // Allocate memory
  nagad_a1w_w_rtype *x = 0, *y = 0;

  if (!(x = NAG_ALLOC(n, nagad_a1w_w_rtype)) ||
      !(y = NAG_ALLOC(n, nagad_a1w_w_rtype)))
    {
      printf("Allocation failure\n");
      exit_status = -2;
    }
  
  if (exit_status==0) {

    // Create AD tape
    nagad_a1w_ir_create();

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

    /* Register variables to differentiate w.r.t. */
    nagad_a1w_w_rtype a;
    a = ar;
    nagad_a1w_ir_register_variable(&a);

    // Initialize variables
    for (int i = 0; i < n; i++) {
      double xr = (1.0*i)/(1.0*(n-1));
      nagad_a1w_w_rtype tmp;
      x[i] = xr;
      tmp = a*x[i];
      y[i] = 4.0/(1.0 + tmp*tmp);
    }

    // Call the AD routine
    ifail = 0;
    nagad_a1w_w_rtype ans, er;
    d01ga_a1w_f_(ad_handle,x,y,n,ans,er,ifail);

    double inc = 1.0;
    nagad_a1w_inc_derivative(&ans,inc);
    nagad_a1w_ir_interpret_adjoint(ifail);

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

    // Get derivative
    double da;
    da = nagad_a1w_get_derivative(a);

    cout.setf(ios::scientific,ios::floatfield);
    cout.setf(ios::right);
    cout.precision(4);
    cout << "\n Solution, ans = ";
    double ans_value = nagad_a1w_get_value(ans);
    cout.width(12); cout << ans_value << endl;
    cout << "\n Derivative:\n";
    cout <<  " d(ans)/da = ";
    cout.width(12); cout << da << endl;

    // Remove computational data object and tape
    x10ab_a1w_f_(ad_handle,ifail);
    nagad_a1w_ir_remove();
  }

  NAG_FREE(x);
  NAG_FREE(y);

  return exit_status;
}