5

I am trying to import data from a saved MATLAB struct array, but it seems that Mathematica is only importing the first element.

MATLAB

blank = struct('x', [], 'y', [], 'z', []);
data = repmat(blank, 1, 10);

for i = 1:10
    data(i) = struct('x', i, 'y', i * 2, 'z', i * 3);
end

save('test.mat', 'data');

Mathematica

In[76]:= Import["test.mat", "LabeledData"]
Out[76]= {"data" -> {"x" -> {{1.}}, "y" -> {{2.}}, "z" -> {{3.}}}}

Does anyone know why this is happening?

As a temporary fix, I've simply resorted to storing multiple struct's in a cell array, i.e.

data{i} = struct(...)

Mathematica seems to be able to handle that fine.

eacousineau
  • 3,457
  • 3
  • 34
  • 37
  • maybe you can change it from an "array of structures" to a "structure of arrays", which has less space overhead anyway: http://stackoverflow.com/questions/4166438/how-do-i-define-a-structure-in-matlab/4169216#4169216 – Amro Jul 04 '11 at 15:38

2 Answers2

2

There is a Mathematica package for interfacing with MATLAB that can transfer structs from MATLAB. See here: MATLink.

This is how you do the transfer in MATLink:

Needs["MATLink`"]

MEvaluate["
 blank = struct('x', [], 'y', [], 'z', []);
 data = repmat(blank, 1, 10);

 for i = 1:10
     data(i) = struct('x', i, 'y', i * 2, 'z', i * 3);
 end"]

MGet["data"]

{{"x" -> 1., "y" -> 2., "z" -> 3.}, {"x" -> 2., "y" -> 4., 
  "z" -> 6.}, {"x" -> 3., "y" -> 6., "z" -> 9.}, {"x" -> 4., 
  "y" -> 8., "z" -> 12.}, {"x" -> 5., "y" -> 10., 
  "z" -> 15.}, {"x" -> 6., "y" -> 12., "z" -> 18.}, {"x" -> 7., 
  "y" -> 14., "z" -> 21.}, {"x" -> 8., "y" -> 16., 
  "z" -> 24.}, {"x" -> 9., "y" -> 18., "z" -> 27.}, {"x" -> 10., 
  "y" -> 20., "z" -> 30.}}

Disclaimer: I am one of the MATLink developers.

Szabolcs
  • 24,728
  • 9
  • 85
  • 174
  • Wow, that looks awesome! I had recently used a similar library, [mlabwrap](http://mlabwrap.sourceforge.net/), for doing a similar thing in Python. These libraries definitely make interfacing easier, so thank you for putting in the work for them! (And will definitely use it when the need arises!) – eacousineau May 02 '13 at 06:05
  • Looks pretty awesome. I have to keep this in mind next time I use MATLAB. Great MATLink website by way, love the design. I have a feeling I will end up emulating a lot of the design concepts from it. – jmlopez May 30 '13 at 19:57
  • @jmlopez Thanks, and I'll pass that on to the person who did the web design :) Feel free to drop me an email if you are having nay trouble with MATLink – Szabolcs May 30 '13 at 20:08
0

I can't really explain the behavior but in order to be able to read the files in Mathematica it is better to specify the Matlab version you are using. In MATLAB try the saving data with version 6.

>> save('test.mat', '-v6', 'data')

Then in mathematica:

In[1]:= Import["test.mat", "LabeledData"]
Out[1]= {"data" -> {"x" -> {{1.}}, "y" -> {{2.}}, "z" -> {{3.}}}, {{2.}}, {{4.}}, {{6.}}, {{3.}}, {{6.}}, {{9.}}, {{4.}}, {{8.}}, {{12.}}, {{5.}}, {{10.}}, {{15.}}, {{6.}}, {{12.}}, {{18.}}, {{7.}}, {{14.}}, {{21.}}, {{8.}}, {{16.}}, {{24.}}, {{9.}},{{18.}}, {{27.}}, {{10.}}, {{20.}}, {{30.}}}

I tried saving with v4 but that doesn't work in MATLAB. Notice that the documentation in Mathematica says that "Import fully supports Versions 4 and 5 of the MAT format.". I Hope this helps.

jmlopez
  • 4,853
  • 4
  • 40
  • 74
  • Sorry, I didn't notice that only the first struct was saved as a list and the rest only as singletons. The only quick solution I can think about is to flatten the data and then partition to get a list we can do this in MATLAB. – jmlopez Jul 04 '11 at 16:11