How do I store data that meet conditions of an if statement

Hi All,
I'm slightly struggling trying to get my code to work, and I hope someone can point me in the right direction.
Very briedly, I have two vectors, 'xx' and 'yy'. I created a matrix using these two vectors, 'xy'. If xy(:,1) is ==1, I would like to store the corresponding cell in xy(:,2) in a seperate variable, 'data'. Otherwise, if the logical expression = 0, I'd like that cell to be a NaN
xx=[-3; -3; -3; -3; -3; -3; 1; -2; -2; -3; -3; -2; 1; 1; 1; -2; 1; 1; ];
yy=[26.28; 36.96; 90.00; 90.00; 90.00; 90.00; 27.85; 29.97; 47.03; 90.00; 67.22; 78.87; 19.60; 9.00; 2.00; 3.41; 1.88; 2.50];
xy=[xx yy];
for i=1:size(xy(:,1),1)
if xy(:,1)==1
data=xy(:,2);
else
data=NaN;
end
end
Thanks in advance.
Cheers

 Accepted Answer

xx = [-3; -3; -3; -3; -3; -3; 1; -2; -2; -3; -3; -2; 1; 1; 1; -2; 1; 1; ];
yy = [26.28; 36.96; 90.00; 90.00; 90.00; 90.00; 27.85; 29.97; ...
47.03; 90.00; 67.22; 78.87; 19.60; 9.00; 2.00; 3.41; 1.88; 2.50];
xy = [xx yy];
data = nan(size(xx));
match = (xx == 1);
data(match) = xy(match, 2);
This "vectorized" method is faster and nicer than a loop. But with a loop:
data = nan(size(xy, 1), 1);
for i = 1:size(xy, 1) % better than: size(xy(:,1),1)
if xy(i, 1) == 1
data = xy(i, 2);
end
end

5 Comments

Thanks for your feedback. I came up with this and it seems to work:
xx = [-3; -3; -3; -3; -3; -3; 1; -2; -2; -3; -3; -2; 1; 1; 1; -2; 1; 1; ];
yy = [26.28; 36.96; 90.00; 90.00; 90.00; 90.00; 27.85; 29.97; ...
47.03; 90.00; 67.22; 78.87; 19.60; 9.00; 2.00; 3.41; 1.88; 2.50];
xy = [xx yy];
for i=1:size(xy(:,1),1)
if xy(i)==1
data(i,:)=xy(i,2);
else
data(i,:)=NaN;
end
end
Probably can be written better, but given my limited MATLAB knowledge, I suppose this is the best I can come up with.
Cheers
Letting the array data grow iteratively needs a lot of ressources. In Each iteration Matlab has to allocate a new array, copy the old values and insert the new value at the end. For e.g. 1e6 element, the OS does not have to allocate 1e6*8 Bytes (a double needs 8 bytes), but sum(1:1e6) * 8 Bytes, which ist more than 4 TB! Although the intemediate arrays are released finally, this is a lot of work for the operating system.
Avoid this by a "pre-allocation": Create the vector with its final size by zeros() or in your case nan(). The latter has the advantage, that you do not have to change the value of the element is not 1.
size(xy(:,1),1) creates the temporary vector xy(:,1) only to measure its size. This is a waste of time, because the size can be measure directly with the original array by: size(xy, 1)
You see the working code including the pre-allocation, using NaN as default and the smarter application of size() in my answer already.
That's very helpful feedback. I will update my code taking into consideration what you have said. Thanks for taking the time to explain - appreciate it. Cheers :)
I posted a demonstration of what happens with dynamic allocation just a day or so ago at<Comment_1298378>
Thanks dpb, thats very useful information. Cheers

Sign in to comment.

More Answers (2)

Don't need any loops nor the explicity xy array that is duplicate of existing data.
data=nan(size(x,1),2); % initialize to NaN
ix=(xx==1); % logical addressing vector of wanted locations
data(ix,:)=[xx(ix) yy(ix)]; % set data values
Alternatively,
data=[xx yy]; % initialize to data
data(data(:,1),:)=nan; % set unwanted values to NaN

1 Comment

I wrote it usuing a for loop because it's a subset of a larger code (and needs to be incorporated within a loop). But thank you for your feedback :) Cheers

Sign in to comment.

You over wrote the variable data. One soluation is to change data to data(i).

1 Comment

The if condition will never be satisfied. if expression is true IFF all elements of expression are true.

Sign in to comment.

Products

Asked:

NA
on 1 Feb 2021

Commented:

NA
on 3 Feb 2021

Community Treasure Hunt

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

Start Hunting!