Layout,graphics and scripting by EyE

Beschrijving hoe Matlab met C++ te combineren is

Vooraf

Matlab en andere programmeertalen communiceren met elkaar middels MEX (Matlab EXecutables) files. Deze MEX files kunnen ook elkaar nog aanroepen. Ook is het mogelijk om in matlab een MEX-file te genereren die daarna met C is aan te spreken. Tot slot heeft Matlab een uitbreidingspakket die het in staat stelt een bepaald matlab programma met GUI en al uit te voeren als ANSI C-code. Hieronder wordt echter alleen ingegaan op de vraag :

Hoe maak ik een MEX-file in C en hoe spreek ik deze aan?

Aan Matlab zijde

De matlab syntax voor het aanroepen van functies is in het algemeen [returnvalues] = functie(parameters).

Voorbeelden:

A = eye(7)
[L, U] = lu(A)
membrane(2)
membrane

Na het maken en compileren van juiste c-file (bijvoorbeeld mijnfunctie.cc), is de syntax voor het aanroepen van deze functie precies hetzelfde:

A = mijnfunctie(7)
[noemer, teller] = mijnfunctie(A, 17)
mijnfunctie(2),

al naar gelang de gewenste (en geimplemeteerde) functionalteit.

Aan de C zijde

Aan C-zijde moeten enkele dingen gebeuren.
  • #include "mex.h" De file mex.h staat in een directory die niet standaard wordt meegelinkt bij het compileren met de standaard compiler, maar wel met de mex-copiler. Indien nodig: de file mex.h is te vinden (in het MI) in de directory /usr/local/matlab/extern/include.
  • Speciale main functie Matlab roept een speciale mainfunctie aan, die de volgende naam en vorm moet hebben:

    extern "C" {
        void mexFunction(int nlhs, mxArray *plhs[],
                         int nrhs, const mxArray *prhs[]){
            /* sourcecode */
        }
    }


    Hier staat nlhs voor aantal argumenten dat geretourneerd moet worden, plhs is een pointer naar de te retourneren data, nrhs is het aantal meegegeven argumenten, en phrs is een pointer naar de megegeven data. Voorbeeld: nhrs=3, dan bestaan er elementen phrs[0], phrs[1] en phrs[2]; deze kunnen gebruikt worden voor berekeningen. Ander voorbeeld: als nlhs=2 dan worden de waarden plhs[0] en plhs[1] uitgelezen door matlab, zodra mexFunction klaar is.
  • MEX-Dataclasses moeten worden gebruikt De data die in prhs wordt meegegeven en de data die gertourneerd moeten worden in plhs zijn in het mxArray formaat. Dit is feitelijk een struct, welke een matrix kan opslaan.
    • Invoeren Bijvoorbeeld op de volgende manier

      int n = mxGetN(phrs[0]);
      int m = mxGetM(phrs[0]);
      double *x = mxGetPr(phrs[0]);
      double **myarray; /* Ook nog alloceren! */
      for(int i=0;i<n;i++)
          for(int j=0;j<m;j++)
              myarray[i][j]=x[j*n+i];


      Maar je kan natuurlijk ook direct de x gebruiken. De variabele phrs[0] bevat nog meer info: de naam, de imaginaire termen van de matrix etc. Functies zoals bijvoorbeeld mxIsChar(phrs[0]) en mxIsClass(phrs[0], "sparse") leveren extra info over het type van de invoer.
    • Uitvoeren Dat kan door middel van bijvoorbeeld
      double *y;
      plhs[0]=mxCreateDoubleMatrix(1,1,mxREAL);
      /* Dit beteklent: Maak een 1 bij 1 matrix met niet complexe doubles als entry's. */
      y = mxGetPr(plhs[0]);
      y[0] = 34.2;
Tot slot zijn er diverse andere typische MEX-functie beschikbaar. Voorbeeld hiervan: mexErrMsgTxt("MEXCPP requires two input arguments.") Ik heb nog geen overzicht + beschrijving van al dit soort functies gevonden, maar allicht helpt het om de file mex.h te bekijken.

Compileren

Compileren moet met de speciale compiler, genaamd mex. (Deze compiler wordt met matlab meegeleverd, en is dus geinstalleerd op het MI in /usr/local/matlab/bin). Het is van belang om de juiste parmaters mee te geven, zodat de syntax wordt:

mex mijnfunctie.cc -f /usr/local/matlab/bin/cxxopts.sh

Nu wordt een file mijnfunctie.mexsol gemaakt. Dit is de gewenste MEX-file.

Eenvoudig Voorbeeld

De file mexcpp.cxx compileert zoals met boventaand commando naar mexcpp.mexsol. In matlab kan deze functie worden aangeroepen middels mexcpp(2, 4). De uitvoer laat zien dat inderdaad de goede waarden aan C worden doorgegeven. Ook geeft het programma een foutmelding als het verkeerde aantal argumenten wordt meegegeven. (Dit is in de C-file geprogrammeerd, het gaat dus niet vanzelf!)

Conclusie

Al met al lijkt het allemaal goed te doen, vooral als je er vanuit gaat dat de matlab gebruiker de juiste invoer meegeeft. In dat geval hoef je namelijk geen checks op de invoer te doen enzo.