Algorithmische Optimale Steuerung - CO2-Aufnahme des Meeres

ADiMat

ADiMat - Quelltransformationstool für Matlab

Homepage an der RWTH Aachen

Für die aktuelle Version muss man das Tool Installieren (für Windows oder Linux möglich, s. Homepage).

Wir haben am Institut auf den Suns eine alte Version installiert unter:

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

Dokumentation.

Die folgende Anleitung bezieht sich auf diese alte Version:

Vorbereitung, Umgebungsvariablen setzen: 

  • shell-Variable ADIMAT_HOME auf das adimat-0.4 Verzeichnis setzen:
    • im Home-Verzeichnis in Datei .bashrc folgende Zeile einfügen:
      • export ADIMAT_HOME=/home/ts/pub/AD/adimat-0.4-r9
      • irgendwo in .bashrc gibt es eine Zeile 
        • export PATH= ...
      • dahinter folgende Zeile einfügen:
        • export PATH=$PATH:$ADIMAT_HOME/bin 
  • neues Terminal aufmachen oder im bisherigen Terminal source .bashrc eingeben (um die Änderungen aktiv zu machen)
  • Fertig!

Differenzieren: Es gibt zwei Möglichkeiten:

  • ADiMat direkt auf eine Funktion y=f(x) in Datei f.m anwenden:
    • In Shell:
      • adimat -i x -d y f.m
  • Matlab-Skriptdatei (z.B. driver.m, keine Funktion!) mit Aufruf der zu differenzierenden Funktion schreiben, Beispiel: x=[0,1]; y=f(x);
    • In dieser Datei Direktiven mit Namen der unabhängigen (independent variables) und der abhängigen Variablen (dependent variables) sowie der Funktion, die differenziert werden soll (toplevel function), einfügen:
      • %ADiMat AD_IVARS = x
      • %ADiMat AD_DVARS = y
      • %ADiMat AD_TOP = f
    • In Shell aufrufen:
      • adimat driver.m

In beiden Fällen ist anschließend eine Funktion [g_y,y] = g_f(g_x,x) in Datei g_f.m generiert.

Aufruf/Einbinden des differenzierten Codes:

  • Datei ADiMat_startup.m aus $ADIMAT_HOME/share/adimat/opt_derivclass in das Verzeichnis kopieren, wo Matlab aufgerufen wird.
  • In Matlab Skript ADiMat_startup (s.o.) aufrufen, oder in startup.m die folgende Zeile schreiben (dann wird es beim Start von Matlab automatisch aufgerufen):
    • ADiMat_startup
  • Seed Matrix g_x erzeugen und initialisieren:
    • g_x=createZeroGradients(n,x);
    • Dabei ist n die Anzahl der Richtungs- oder partiellen Ableitungen, die man berechnen will, also für die volle Jacobi-Matrix n= length(x).
    • Einzelne Komponenten von g_x setzen:
      • n=1: i-te partielle Ableitung: g_x{1}(i)=1;
      • n=1: Richtungsableitung in Richtung d: g_x{1}=d;
      • n=length(x): volle Jacobi-Matrix: for i=1:n, g_x{i}(i)=1; end
  • Nach Aufruf von g_f steht die Ableitung in g_y

Adol-C

Adol-C ist ein Operatorüberladen-Tool für C++

Homepage

Adol-C kann dort heruntergeladen werden. Es wird normalerweise im Heimatverzeichnis ($HOME) in einem Unterverzeichnis 

adolc_base 

installiert.

Es kann mit oder ohne Tape gearbeitet werden:

  • Tapeless Mode (nur Vorwärtsmodus):
    • Programmcode vorbereiten:
      • Headerfile einbinden:
        #include "adolc/adtl.h"
      • Speziellen Namensbereich für "tapeless" benutzen: 
        using namespace adtl;
      • max. Anzahl der unabhangigen Variablen setzen (hier n): 
        setnumDir(n);
      • alle aktiven Variablen und Funktionen als Typ 
        adouble
        deklarieren
      • mit
        x[i].setADValue(i,1)
        initialisiert man die Seed Matrix (hier dx[i]/dx[i]=1)
      • mit
        y.getADValue(i)
        erhält man die i-te Komponente der Ableitung (hier für y=f(x))
    • Übersetzen: mit Option 
      
      		
      				-I/$HOME/adolc_base/include
      
    • Linken: mit Option
      
      				-L/home/numtools/adolc_base/lib64 -ladolc
    • Tape Mode (Vorwärts- und Rückwartsmodus):
      • Programmcode vorbereiten:
        • Headerfile einbinden: #include "adolc/adolc.h"
        • Tape initialisieren: Vor dem zu differenzierenden Programmteil:  trace_on(tag,keep); Dabei ist tag die Tapenummer (wenn man nur eins benötigt also tag=0) Parameter keep (optional) wird nur bei einem direkt folgenden (d.h. ohne zuerst einmal forward mode benutzt zu haben) reverse mode-Aufruf benötigt und wird dann auf die Ordnung der höchsten zu berechnenden Ableitung gesetzt (also bei 1. Ableitung mit reverse mode : trace_on(0,1))
        • Werte der unabhängigen Variaben in die adouble-Variablen "shiften", Beispiel: double x[n]; adouble ax[n];   for (i=0;i<n;i++) ax[i] <<= x[i];
        • danach alle aktiven Variablen als Typ adouble deklarieren und Programmcode sonst unverändert lassen, Beispiel: adouble f(adouble*); adouble ay; ay=f(ax);
        • Ergebnis zurück in adouble-Variable shiften: double y;  ay >>= y;
        • Tape abschalten:  trace_off();
      • Berechnen der Ableitung durch Auswerten des Tapes:
        • Direkt forward mode aufrufen (Manual S. 41):
          • Jacobi-Matrix für eine Funktion f:R^n-> R^m:  Seed Matrix definieren und initialisieren:  double **X=new double*[n];  ...   Jacobi-Matrix definieren: double**Y = new double*[m]; for(int i=0;i<m;i++) Y[i]=new double[n]; Aufruf Vorwärtsmodus: forward(tag,m,n,n,x,X,y,Y);     // y=Vektor der Funktionswerte
          • Gradient einer Funktion f:R^n-> R: Seed Matrix definieren und initialisieren:  double **X=new double*[n];  ... Gradientenvektor definieren: double*Y = new double[n]; Aufruf Vorwärtsmodus: forward(tag,m,n,n,x,X,&y,&Y);     // y= Funktionswert (skalare Größe, daher Referenz übergeben!)
        • Direkt reverse mode aufrufen (Manual S. 40):
          • Gradient einer Funktion f:R^n -> R:

            double w=1; double *Y = new double[n]; reverse(tag,1,n,0,&w,Y); Dabei muss bei trace_on() s.o.  keep=1 gewesen sein oder einmal ein forward mode-Lauf vorausgegangen sein!!!

    • oder Treiber für Gradient etc.:
      • Gradient in x auswerten und in Array grad speichern  double grad[n];  gradient(tag,n,x,grad);  // tag hat gelichen Wert wie bei trace_on
      • Hesse-Matrix (2. Ableitungen):  double H[n][n];  hessian(tag,n,x,H);
    • Übersetzen wie beim Tapeless Mode
    • Linken:  AdolC-Bibilotheken mit angeben:    -L/home/numtools/adolc_base/lib -ladolc -R/home/numtools/adolc_base/lib    ( - "klein L" adolc  in der Mitte!!!)

TAC++

(Transformation of Algorithms in C++)

Quelltransformationstool für C/C++ der Fa. FastOpt Hamburg, befindet sich in der Entwicklung.

Homepage des Tools

Remote-Zugang über ein Skript   (Zugangscode erforderlich, bei Interesse bitte wenden an: Thomas Slawig)

Benutzung:

  • zu differenzierende Funktion in eine void-Funktion schreiben, Beispiel y=f(x): void f(double y, double x) in Datei f.c)
  • Aufruf für Vorwärtsmodus: stac++ -remote -toplevel f  -input x -output y -l - -forward f.c
  • Aufruf für Rückwärtsmodus: stac++ -remote -toplevel f  -input x -output y -l - -reverse f.c
  • In den Dateien f_tl.c (VW) bzw. f_ad.c (RW) befinden sich die differenzierten Funktionen