32 views (last 30 days)

Show older comments

A matrix M is preallocated with NaN's:

M=NaN(4,3)

NaN NaN NaN

NaN NaN NaN

NaN NaN NaN

NaN NaN NaN

Then an array x is put into a column:

x=1:4

M(:,2)=x

NaN 1 NaN

NaN 2 NaN

NaN 3 NaN

NaN 4 NaN

This will only work if x is as long as the height of M. My question is about how to efficiently handle cases where x is either too small or too big.

- In case of a too small x, I want it to replace as much as it can starting from the first row, giving:

x=1:2

M(:,2)=x

_Do-something-so-a-smaller-x-is-accepted_

NaN 1 NaN

NaN 2 NaN

NaN NaN NaN

NaN NaN NaN

- Whereas in case of a too big x, I want M to grow in height like this:

x=1:5

M(:,2)=x

_Do-something-so-M-will-grow-to-fit_

NaN 1 NaN

NaN 2 NaN

NaN 3 NaN

NaN 4 NaN

NaN 5 NaN

I would like to ask the community for the simplest and most efficient method to merge the matrix and array in this dynamic way, making the matrix grow if needed or allowing for insertion of a too small x if needed in the ways shown above.

The method I use at the moment is with an if-elseif-statement that does concatenation on the matrix with a lot of extra NaN's if x is larger and extension of x with a lot of NaN's if it is smaller. I find it a bit tedious and messy and hope to hear if there is a cleaner solution out there:

if size(x,1) > size(M,1)

fillingUp = nan(size(x,1)-size(M,1) , size(M,2));

M = cat(1,M,fillingUp);

elseif size(x,1) < size(M,1)

fillingUp = nan(1 , size(M,1)-size(x,1));

x = [x fillingUp];

end

M(:,2)=x;

David Fletcher
on 13 Apr 2018

Stephen Cobeldick
on 13 Apr 2018

Edited: Stephen Cobeldick
on 13 Apr 2018

"I find it a bit tedious and messy and hope to hear if there is a cleaner solution out there"

I doubt it. Sometimes code is tedious and messy. So put it into a function called resizealloc or whatever, and then you can call it and keep the rest of your code nice and tidy.

It is certainly possible to implicitly expand arrays by allocating to elements outside their current size, but this adds zeros for all unallocated values. For adding NaNs there is not much choice apart from doing something like that in your question.

John D'Errico
on 13 Apr 2018

njj1
on 13 Apr 2018

Why not create the matrix M such that it's size is [numel(x), num_of_desired_columns]? For example, if num_of_desired_columns = 3:

M = NaN(numel(x),3);

M(:,2) = x;

If you want to use the if-else statement, then modify it:

if size(M,1)~=numel(x)

M = NaN(numel(x),3);

M(:,2) = x;

end

njj1
on 13 Apr 2018

I'll tell you what I'm imagining here and then a solution to that imagined problem.

You have a matrix M which is initialized as M = NaN(n,k). You then have a vector x that is introduced, size(x) = [rx,1]. You want to merge these two matrices. But, let's say you already have some data in M.

M =

NaN 1 NaN

NaN 2 NaN

NaN 3 NaN

NaN 4 NaN

NaN NaN NaN

NaN NaN NaN

So, you want to put the vector x in the second column and grow M around it. My suggestion is to find the row where numerical data is no longer in M and then stack x surrounded by NaN's under M.

if size(x,1)~=size(M,1)

M(isnan(M(:,2)),:) = []; %this blanks out all rows where NaN only exist (rows 4 and 5 in the above example)

M = [M;[NaN(numel(x),1),x,NaN(numel(x),1)]]; %this stacks M on top of new data, x, that is constrained between two columns of NaN's

end

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!