Search code examples
matlabappendmat-file

Append data to a saved variable using matfile()


I have some random 2D data fuffa that I save to a file fuffalo:

fuffa=rand(10,10);
save('fuffalo','fuffa', '-v7.3')

I then go through a loop that generates other fuffa data that I want to append (in the third dimension) to the saved variable. To do this, I tried to apply this suggestion:

m1 = matfile('fuffalo.mat', 'Writable', true);

for ii=1:3
   fuffa2=rand(10,10);    
   m1.fuffa(1:10,1:10,end+1)=fuffa2;
end

However, at ii=2 I get the following error:

Variable 'fuffa' has 2 dimensions in the file, this does not match the 3 dimensions in the indexing subscripts.

How can I convince MATLAB to append in the third dimension?


Solution

  • Because you are accessing the file on disk, not a workspace variable, you may be encountering issues with expanding the number of dimensions. You would not have this issue dealing with variables which are stored in-memory (like if you used load instead of matfile).

    To avoid this, the best approach would be pre-allocation. I'm going to assume though that this is a simplification of your actual problem, and you need to be able to do such 3D extensions to a potentially 2D array.

    In this case, just use cat to concatenate in the 3rd dimension:

    fuffa=rand(10,10);
    save('fuffalo','fuffa', '-v7.3')
    m1 = matfile('fuffalo.mat', 'Writable', true);
    for ii=1:3
        fuffa2=rand(10,10);
        % Concatenating in the 3rd dimension, avoiding used 'end' which 
        % assumes that dimension already exists
        m1.fuffa=cat(3,m1.fuffa,fuffa2);
    end
    % m1.fuffa <10x10x4 double>
    

    Note that by doing this, you are bringing the entirety of your .mat data into memory for the concatenation, defeating the point of matfile(). However, your previous method would face the same problem, since in the docs we see:

    Using the end keyword as part of an index causes MATLAB to load the entire variable into memory.

    As stated before, you're probably better off with pre-allocation!