Search code examples
matlab

Save a cell array full of structs into mat file


How can I save a cell array full of structs into a mat file in matlab? When I try this code:

save('fileName.mat', 'output', '-v7.3')

the mat file is full of cells that display {0×0 double}. I can store each struct individually, but not the whole cell array. I'm trying not to use dynamic variable names (storing structs one at a time in a loop will overwrite them because the variable name will always be the same).


Solution

  • 1.- ALL variables smaller than 2GB

    I assume you have already checked this one.

    Just 1 variable size > 2GB and save does not cherry pick, it just does not save anything at all.

    I like the attempt mentioned in the question of saving variables one by one, so since it's also mentioned that there's a large amount of variables I am going to show how to do it with the powerful MATLAB command evalin

    1.- Simulating data

    N=20  % <100
    L=[1:N];
    vals=randi([-1000 1000],1,N);
    

    2.- Generating temporary support variables

    strL='//';
    for k=1:1:numel(L)
        str0=['0' num2str(L(k))];
        if L(k)<10 
            strL=[strL;str0]; 
        else
            strL=[strL;num2str(L(k))];
        end
    end
    strL(1,:)=[];
    
    for k=1:1:numel(L)
        str1=['store' strL(k,:) '=' num2str(vals(k))];
        evalin('base',str1)
    end
    

    20 temporary variables have been generated.

    3.- Start saving to .mat

    save file01.mat store01
    for k=2:1:numel(L)
        str2=['save file01.mat store' strL(k,:) ' -append'];
        evalin('base',str2)
    end
    

    4.- Clean the workspace

    storeXX variables are temporary, just for this specific storage into .mat

    for k=1:1:numel(L)
        str3=['clear store' strL(k,:)];
        evalin('base',str3)
    end
    

    5.- load .mat files with command load

    Self explained.

    Command load allows to cherry pick any particular variable or group of variables in a given .mat file.

    6.- Merging loaded variables

    into the one structure mentioned in the question can be simplified in similar manner. Let me know if you would like an example on this point.

    7.- and clean up temporary variables

    Once struct rebuilt.

    Again the particulars of the mentioned struct are unknown.

    Additional Comments

    8.- Mathworks recommends always validate evalin input strings

    It's mentioned, for security considerations, to validate ALL evalin input strings, ALWAYS.

    But since it seems to be obvious that the Ruby is in control of all the data, such security consideration does not apply to this particular case.

    YES it's unwise to feed evalin with non-validated strings,

    BUT ANYWAY isn't it unwise FOR ANY COMMAND, to feed them non-validated data ?!?

    Validating inputs is not an evalin only consideration, it's common sense FOR ANY COMMAND when handling critical data.

    Don't we all check what's on the pizza before going for it?

    9.- Do not build strings in evalin input field

    It's also recommended to use

    evalin('base',expression)
    

    as shown above in this answer, instead of building strings in the same evalin input field, for instance

    evalin('base',['output=' expression])
    

    Aagain common sense: that should the most common of the senses.

    build the string first, this way it's easy, or should be easy to validate (or put aside/ flag / reject) it, and then if valid data use evalin

    evalin a mighty MATLAB command indeed that allows to write code that writes code.