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

NAG AD Library Introduction
Example description
/* nag::ad::g02ab Passive Example Program.
 */

#include <dco.hpp>
#include <iostream>
#include <nagad.h>

std::stringstream filecontent("4 \
 2.0   -1.0    0.0    0.0 \
-1.0    2.0   -1.0    0.0 \
 0.0   -1.0    2.0   -1.0 \
 0.0    0.0   -1.0    2.0 \
100.0   20.0   20.0   20.0");

// Function which calls NAG AD routines.
// Computes the Nearest Correlation Matrix X for an input matrix G.
template <typename T>
void func(std::vector<T> &g, std::vector<T> &w, std::vector<T> &x);

int main()
{
  std::cout << " nag::ad::g02ab Passive Example Program Results\n";

  Integer n;
  filecontent >> n;

  // Input Matrix G, whose NCM we want to compute
  std::vector<double> gv(n * n);
  for (int i = 0; i < n; ++i)
  {
    for (int j = 0; j < n; ++j)
    {
      filecontent >> gv[i + j * n];
    }
  }

  // The square roots of the diagonal elements of W
  std::vector<double> wv(n);
  for (int i = 0; i < n; i++)
  {
    filecontent >> wv[i];
  }

  // Output NCM X
  std::vector<double> xv(n * n);

  // Call the NAG AD Lib functions
  func(gv, wv, xv);

  std::cout.setf(std::ios::scientific, std::ios::floatfield);
  std::cout.precision(12);
  std::cout << "\n Nearest Correlation Matrix:\n\n";
  for (int i = 0; i < n; i++)
  {
    for (int j = 0; j < n; j++)
    {
      std::cout.width(20);
      std::cout << xv[i + j * n];
    }
    std::cout << std::endl;
  }

  return 0;
}

// Function which calls NAG AD routines.
template <typename T>
void func(std::vector<T> &g, std::vector<T> &w, std::vector<T> &x)
{
  Integer n   = sqrt(g.size());
  Integer pdg = n;
  Integer pdx = n;

  // Set up method parameters
  T       errtol = 0.0, alpha = 0.02;
  Integer maxits = 0;
  Integer maxit  = 0;
  // Output variables
  Integer iter, feval;
  T       nrmgrd;
  // Set a copy of g, since it will be modified by the example
  std::vector<T> g_tmp = g;
  // Create AD configuration data object
  Integer           ifail = 0;
  nag::ad::handle_t ad_handle;

  // Routine for computing the NCM of G.
  nag::ad::g02ab(ad_handle, g_tmp.data(), pdg, n, "B", alpha, w.data(), errtol,
                 maxits, maxit, x.data(), pdx, iter, feval, nrmgrd, ifail);

  ifail = 0;
}