In an earlier post I did a review of different C/C++ libraries for scientific computing (among them IT++, GSL, and others) and concluded that the armadillo linear algebra library has a lot of functions, is very easy to use, and very fast. So, I thought it would be very nice to make it work within mex functions. This could make functions in C++ both very legible and easy to write at the same time fast.
I managed to do this and in this post I explain how.
It is kind of a hack, but works smoothly without problems, although the compilation was first a hassle that took some time. See the end of this post on how to compile.
The trick is to first create an armadillo structure and then let its pointer indicate the input structure from matlab (dimensionality of the structure has to be adapted, if not you get segfaulted). When the function ends, armadillo wants to destroy its structures, so before, you have to make it point to the original location and adapt dimensionality (or else...).
Here comes a toy example of a mex file that should illustrate how to use it with matlab.
Compilation:If you don't have it yet, take 5 minutes to install the armadillo library.
For compilation you should include the additional compiler switches -lcblas -DARMA_NO_DEBUG. In an ideal world you would only have to type this:
>> mex toy_example.cpp -lcblas -DARMA_NO_DEBUG
Unfortunately this is not an ideal world. While this compiled for me without problems, on execution of the function within matlab, I got this error a lot:
invalid mex file.
GLIBCXX_3.4.9' not found
I first sym-linked matlab-provided shared libraries (.so files) to the ones of my system. I am not sure this is a good idea and anyways it didn't solve the problem. I edited heavily the mexopts.sh file which gives the parameters to mex compiler, however this did not help, it didn't seem to take these parameters. I finally compiled from bash prompt by a variation of the commands I found mex used (use -v switch with mex). The commands that work for me are these (you might have to adapt them slightly):
>> g++ -c -I/opt/matlab/extern/include -I/opt/matlab/simulink/include -DMATLAB_MEX_FILE -ansi -fPIC -fno-omit-frame-pointer -pthread -DMX_COMPAT_32 -DNDEBUG -DARMA_NO_DEBUG "toy_example.cpp"
>>g++ -c -I/opt/matlab/extern/include -I/opt/matlab/simulink/include -DMATLAB_MEX_FILE -ansi -D_GNU_SOURCE -fexceptions -fPIC -fno-omit-frame-pointer -pthread -DMX_COMPAT_32 -O3 -DNDEBUG "/opt/matlab/extern/src/mexversion.c"
>>g++ -O3 -pthread -shared -Wl,--version-script,/opt/matlab/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -o "toy_example.mexa64" mahal_dist.o mexversion.o -Wl,-rpath-link,/opt/matlab/bin/glnxa64 -L/opt/matlab/bin/glnxa64 -lmx -lmex -lmat -lm -lcblas
Hope you enjoy using this. Please also see my mex implementation of the mahalanobis function.
Happy coding! Please leave comments below.