Quite a while ago I was looking at ways to interface between MATLAB and a C++ program for a job at university. In the end I wrote a C++ wrapper for the C API to access MAT files which turned out to be quite useful. Since it’s small and easy to use, I decided to release it.
At first the plan was to make the program into a MEX file (basically a dynamically linked extension program), but I quickly ran into a problem with deal II (an excellent, well documented and object-oriented library for solving partial differential equations with adaptive finite elements): MATLAB altered some of the floating point precision settings which lead to an algorithm in deal II running in an infinite loop (the epsilon value was hardcoded at that time and basically became zero). While the bug was promptly fixed, there were other issues and it was decided that embedding the program was not worth the trouble.
Long story short, I needed a way to read and write the MAT files that MATLAB generates and loads with the ‘load’ and ‘save’ commands. Using the C API directly seemed cumbersome and error prone, so this C++ wrapper was born.
Download it (4 kB) as .tar.bz2 or as zip.
A basic use case looks like this (also check out test.cc):
#include "matlabfile.h"
using namespace MatlabUtilities;
File matfile("some.mat");
std::vector<double> vec1;
matfile.read<Types::real_vector>("v1", vec1);
double[100] vec2;
matfile.read<Types::fixed_length_real_vector<100> >("v2", vec2);
matfile.write<Types::string>("hw", "Hello World!");
Not all MATLAB types are implemented (check Types namespace in matlabaccessors.h for a list), in particular real matrices with a column and row length different from one are missing for two reasons: I didn’t need them for the job and you probably have your own preferred matrix type anyway. But don’t worry, the template-design makes it easy to add these missing features. What needs to be implemented is
struct real_matrix {};
template <>
struct Reader<real_matrix, MyMatrix> {
static void read(mxArray* var, MyMatrix& result);
}
template <>
struct Writer<real_matrix, MyMatrix> {
static mxArray* write(MyMatrix& source);
}
template <>
struct TypeCheck<real_matrix> {
static bool typeCheck(mxArray* var);
}
where the ‘read’ function reads data from the mxArray into result, ‘write’ returns a new mxArray filled with source’s data and ‘typeCheck’ returns true if the mxArray contains a real_matrix. With these template specializations in place you can use the new code like this:
MyMatrix mat;
matfile.read<real_matrix>("somevarname", mat);
matfile.write<real_matrix>("someother", mat);
Similarly, you can add a new reader to say ‘real_vector’ to accomodate for your own vector type.
The code snippet only contains code for reading and writing data. Other management functionality, like listing all fields in a MAT file is not implemented. I hope it will nevertheless be useful for someone.
Comments 5
Hey! Great, thank you!!! Saves me a bit of time :-)
I think, although this is only a very small thing, that you should upload a ZIP file. Some people have to use Windows, and although Linux supports many formats very easily, ZIP is mostly what the windows world settles for. So ZIP files are more directly cross platform.
Anyway, great and thank you!
Posted 25 Jan 2008 at 9:35 ¶I’m glad you find it useful. I also added an alternative zip file download to the article.
Be aware that I’ve never tried to compile that code with the Windows Matlab. Since it only uses the Matlab api, I expect it to work though.
Posted 25 Jan 2008 at 12:55 ¶Thanks for this great tool.
Posted 17 Dec 2008 at 19:56 ¶Hi Christian,
Do we need to have matlab installed on the LINUX operating system which we are running??
Cheers
Posted 22 Apr 2009 at 7:59 ¶> Do we need to have matlab installed on the LINUX operating system which we are running??
Technically, no. But if you linked to the MATLAB libraries dynamically, you will require the libraries on the target computer. You could link them statically, of course.
Posted 22 Apr 2009 at 17:23 ¶