Algorithmic Optimal Control - CO2 Uptake of the Ocean

Adol-C

Adol-C is a operator-overload-tool for C++

Homepage

Installed at the Department of Computer Science under

/home/numtools/adolc_base/

There are two different Modes:

  • Tapeless Mode (only forwards mode):
    • prepare program code:
      • define macro ADOLC_TAPELESS:  #define ADOLC_TAPELESS
      • maximum number of independent variables: #define NUMBER_DIRECTIONS 10
      • (Afterwards!!!) include header file: #include "adolc/adolc.h"
      • use special namespace for "tapeless": using namespace adtl;
      • declare all active variables and functions as type adouble
      • initialize the Seed-Matrix via  x[i].setADValue(i,1) (here dx[i]/dx[i]=1)
      • Get the i-th component of the derivative via y.getADValue(i)  (here for y=f(x))
    • Compile: with option -I/home/numtools/adolc_base/include  ( - capitali)
    • Link: no further library is needed
  • Tape Mode (forwards and backwards mode):
    • prepare program code:
      • include header file: #include "adolc/adolc.h"
      • initialize tape: Before the part of the program that will be differentiated: 
        trace_on(tag,keep);
        tag is the tapenumber (if you only need one, set tag=0)
        Parameter keep (optional) is only necessary if there's a call for reverse mode directly afterwards (without using the forwards mode first) and is set to the order of the highest derivative that will be calculated (thus trace_on(0,1) for 1. derivative in reverse mode)
      • Shift values of the independent variables into the adouble variables. Examplel:
        double x[n];
        adouble ax[n];  
        for (i=0;i<n;i++) ax[i] <<= x[i];
      • The declare all actice variables as type adouble and don't change the rest of the program code, Example:
        adouble f(adouble*);
        adouble ay;
        ay=f(ax);
      • Shift result back into adouble-Variable:
        double y; 
        ay >>= y;
      • deactivate tape: 
        trace_off();
    • Calculate the derivative by evaluating the tape:
      • Directly call forward mode (Manual p. 41):
        • Jacobian matrix for a function f:R^n-> R^m: 
          define and initialize Seed Matrix : 
          double **X=new double*[n]; 
          ...
            define Jacobian matrix:
          double**Y = new double*[m];
          for(int i=0;i<m;i++) Y[i]=new double[n];
          Call forward mode:
          forward(tag,m,n,n,x,X,y,Y);     // y=vector of function values
        • Gradient of a function f:R^n-> R:
          define and initialize Seed-Matrix: 
          double **X=new double*[n]; 
          ...

          define gradient vektor:
          double*Y = new double[n];
          Call forward mode:
          forward(tag,m,n,n,x,X,&y,&Y);     // y= function value (scalar size, thus deliver reference)
      • Call reverse mode directly (Manual p. 40):
        • Gradient of a function f:R^n -> R:

          double w=1;
          double *Y = new double[n];
          reverse(tag,1,n,0,&w,Y);

          It is either necessary to set keep=1 in trace_on() or a run in forward mode must have been executed!!!

  • or drivers for Gradient etc.:
    • Examine gradient in x and save in Array grad 
      double grad[n]; 
      gradient(tag,n,x,grad);  // tag as the same value as in trace_on
    • Hessian-Matrix (2. derivatives): 
      double H[n][n]; 
      hessian(tag,n,x,H);
  • Compile as in tapeless mode
  • Link:  AdolC libraries are necessary:  
     -L/home/numtools/adolc_base/lib -ladolc -R/home/numtools/adolc_base/lib    ( - "small L" adolc  in the middle!!!)