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>

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;

  printf("X10AA_A1W_F C Header Example Program Results\n\n");

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

  printf("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) {
    printf("Symbolic computational mode is being used\n\n");
  } else if (mode==nagad_algorithmic) {
    printf("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==-199) {
    printf("%s %4"NAG_IFMT" \n\n",
           "AD computation failed as expected with ifail = ", ifail);
  } else {
    printf(" Unexpected IFAIL returned in AD computation\n");
    printf("%s %4"NAG_IFMT" \n","   ifail expected: ", ierr_not_implemented);
    printf("%s %4"NAG_IFMT" \n\n","   ifail returned: ", ifail);
    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) {
    printf("Symbolic computational mode is being used\n\n");
  } else if (mode==nagad_algorithmic) {
    printf("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);

  printf("%28s : %11.3e\n", "Input value of x", x.value);
  printf("%28s : %11.3e\n", "Output value of ln(1+x)", y1);
  printf("%28s : %11.3e\n", "AD evaluated derivative", dydx);
  printf("%28s : %11.3e\n", "Directly computed derivative", dydx_exp);

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