NAG Library Manual, Mark 30
Interfaces:  FL   CL   CPP   AD 

NAG AD Library Introduction
Example description
/* E01EA_T1W_F C++ Header Example Program.
 *
 * Copyright 2024 Numerical Algorithms Group.
 * Mark 30.0, 2024.
 */

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

int main()
{
  // Scalars
  int exit_status = 0;

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

  // Skip first line of data file
  string mystr;
  getline(cin, mystr);
  // Read number of data points
  Integer n;
  cin >> n;

  // Allocate arrays for data and interpolant
  nagad_t1w_w_rtype *x = 0, *y = 0, *f = 0;
  Integer *          triang = 0;
  x                         = new nagad_t1w_w_rtype[n];
  y                         = new nagad_t1w_w_rtype[n];
  f                         = new nagad_t1w_w_rtype[n];
  triang                    = new Integer[7 * n];

  // Create AD configuration data object
  Integer           ifail = 0;
  nag::ad::handle_t ad_handle;

  // Read data and register variables
  for (int i = 0; i < n; i++)
  {
    double xr, yr, fr;
    cin >> xr >> yr >> fr;
    x[i] = xr;
    y[i] = yr;
    f[i] = fr;
  }

  ifail = 0;
  nag::ad::e01ea(n, x, y, triang, ifail);
  // Evaluate interpolant and derivatives at a mid-point
  nagad_t1w_w_rtype px[1], py[1], pf[1];
  double            xint, yint;
  xint  = 0.5 * (dco::value(x[n / 2 - 1]) + dco::value(x[n / 2]));
  yint  = 0.5 * (dco::value(y[n / 2 - 1]) + dco::value(y[n / 2]));
  px[0] = xint;
  py[0] = yint;

  // Call the AD routine
  double  inc = 1.0, zero = 0.0;
  Integer m              = 1;
  dco::derivative(px[0]) = inc;
  ifail                  = 0;
  nag::ad::e01eb(ad_handle, m, n, x, y, f, triang, px, py, pf, ifail);
  double dx              = dco::derivative(pf[0]);
  dco::derivative(px[0]) = zero;

  dco::derivative(py[0]) = inc;
  ifail                  = 0;
  nag::ad::e01eb(ad_handle, m, n, x, y, f, triang, px, py, pf, ifail);
  double dy = dco::derivative(pf[0]);

  cout << "\n Interpolant point: x = " << xint << " y = " << yint << endl;
  cout.precision(5);
  cout << " Interpolated value = " << dco::value(pf[0]) << endl;

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

  cout.setf(ios::scientific, ios::floatfield);
  cout.precision(4);
  cout << "\n Derivatives of fitted value w.r.t. fit point:\n\n";
  cout << "     d/dx  = " << dx << endl;
  cout << "     d/dy  = " << dy << endl;

  delete[] x;
  delete[] y;
  delete[] f;
  delete[] triang;
  return exit_status;
}