|
|
|
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.
|