Algorithmic Optimal Control - CO2 Uptake of the Ocean

ADIMat

ADiMat - Sourcetransformationtool for Matlab

Homepage at the RWTH Aachen

To use the current version you have to install the Windows or Linux tool (see homepage).

Theres an old version installed on the sun system at the Department of Computer Science under

  • /home/ts/pub/AD/adimat-0.4-r9 (Solaris Sun-Sparc-Architektur, z.B. auf Rechner sauron)

Documentation.

The following tutorial refers to that old version:

Preparation, set shell variables: 

  • set shell-Variable ADIMAT_HOME to directory adimat-0.4 :
    • (in homedirectory) enter the following line into the file .bashrc :
      • export ADIMAT_HOME=/home/ts/pub/AD/adimat-0.4-r9
      • somewhere in .bashrc there's a line  
        • export PATH= ...
      • enter the following line behind that line:
        • export PATH=$PATH:$ADIMAT_HOME/bin 
  • open new terminal or enter source .bashrc into the current terminal (to activate the changes)
  • Done!
 

Differentiate: There are two possibilities:

  • Apply ADiMat directly onto a function y=f(x) in file f.m:
    • In shell:
      • adimat -i x -d y f.m
  • Write a Matlab-Skriptfile that calls the function you want to differentiate (e.g. driver.m, not just a function!), for example: x=[0,1]; y=f(x);
    • Enter directives with names of  independent variables, dependent variables and the function yo want to differentiate into this file:
      • %ADiMat AD_IVARS = x
      • %ADiMat AD_DVARS = y
      • %ADiMat AD_TOP = f
    • Call in shell:
      • adimat driver.m

In both cases a function [g_y,y] = g_f(g_x,x) will be generated in file g_f.m .

Call/Embedding of the differentiated code:

  • Copy the file ADiMat_startup.m from $ADIMAT_HOME/share/adimat/opt_derivclass into the directory from which Matlab is called.
  • Call Skript ADiMat_startup (see above.) in Matlab, or write the following line into startup.m  (to automatically call it when starting Matlab):
    • ADiMat_startup
  • Generate and initialize Seed Matrix g_x :
    • g_x=createZeroGradients(n,x);
    • n is the number of directional or partial derivatives to be calculated, you thus need n= length(x) for a full Jacobian matrix
    • Set individual components of g_x:
      • n=1: i-th partial derivative: g_x{1}(i)=1;
      • n=1: directional derivative in direction of d: g_x{1}=d;
      • n=length(x): full Jacobian matrix: for i=1:n, g_x{i}(i)=1; end
  • After calling g_f the derivative can be found in in g_y

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!!!)

TAC++

(Transformation of Algorithms in C++)

Sourcetransformationtool for C/C++, is still in development by FastOpt Hamburg.

Homepage of the tool

Remote-acces via script   (access code necessary, if interested please contact: Thomas Slawig)

Use:

  • write the function you want to differentiate into a void function, Example: y=f(x): void f(double y, double x) in file f.c
  • Call for forwards mode: stac++ -remote -toplevel f  -input x -output y -l - -forward f.c
  • Call for backwards mode: stac++ -remote -toplevel f  -input x -output y -l - -reverse f.c
  • The derivatives can be found in files f_tl.c (VW) and f_ad.c (RW)