The size function does not return the right number

%trim the calibrated data
m = unique([in_M, code_M],'sorted', 'rows');
[len, notImp] = size(m);
for j = 1:1:len
if m(j,2) > 4095
m(j,:) = [];
else
continue;
end
end
The size of m is 999961 x 2, but the returned value of the number of rows(len) is 1000001
Could you help me with this matter? Thank you in advance!

4 件のコメント

Stephen23
Stephen23 2022 年 11 月 10 日
編集済み: Stephen23 2022 年 11 月 10 日
After measuring its size your code removes rows of m:
if m(j,2) > 4095
m(j,:) = [];
..
After that code has run, it is entirely expected that m will have <=1000001 rows. Which apparently it does.
So far everything is behaving exactly as expected, it is unclear what the problem is.
Xin
Xin 2022 年 11 月 10 日
Hi Stephen,
Thank you for the comments.
The problem is when I try to run the codes, this error shows up. I guess the index means len. What would you recommend to do to fix this error? Thank you!
Stephen23
Stephen23 2022 年 11 月 10 日
The problem is that inside the loop you are removing rows and then trying to access rows which no longer exist.
Consider this vector: [1,2,3,4]
we start running a loop over it and remove the 2nd element, so the vector now look like this: [1,3,4]
then the loop keeps running and then we try to remove the 4th element. But does the vector have a 4th element? (hint: no)
Thus the error: you are trying to remove rows which do not exist.
The usual solution is to loop over the rows from bottom to top:
for j = len:-1:1
Xin
Xin 2022 年 11 月 10 日
It works!!!
Thank you so much for your comments!

サインインしてコメントする。

 採用された回答

Jan
Jan 2022 年 11 月 10 日
編集済み: Jan 2022 年 11 月 10 日

0 投票

You do not even need a loop:
m = unique([in_M, code_M],'sorted', 'rows');
[len, notImp] = size(m);
m = m(m(j,2) <= 4095, :);
This is even faster. The iterative shrinking of arrays is as expensive as the growing. Example:
x = [];
for k = 1:1e6
x(k) = k * rand;
end
The final array has 8 MB only (8 byte per double). But in each iteration a new array is created an the contents of the old one is copied. This let Matlab allocate sum(1:1e6)*8 bytes : over 4 TB ! Although the memory is released in the next iteration, this is a lot of work. A small change can avoid this - pre-allocation:
x = zeros(1, 1e6); % Pre-allocation
for k = 1:1e6
x(k) = k * rand;
end
Now only the final array of 8 MB is allocated.
Using the logical indexing m(j,2)<=4095 avoid the iterative change of the array also.
Another hint: continue let the loop perform the next iteration. In your case this is useless, because this the obvious next step at all. So simply omit the "else continue".

1 件のコメント

Xin
Xin 2022 年 11 月 10 日
Thank you for the detailed explanation. Very useful!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeLoops and Conditional Statements についてさらに検索

製品

タグ

質問済み:

Xin
2022 年 11 月 10 日

コメント済み:

Xin
2022 年 11 月 10 日

Community Treasure Hunt

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

Start Hunting!

Translated by