Array idx bug when resizing it

3 views (last 30 days)
Ciro Bermudez
Ciro Bermudez on 26 May 2021
Commented: dpb on 26 May 2021
我在做策划一个分岔图的代码, but when testing I found out that jumps one step at the beginning. I also tested this in the Online version and the same behavior is present, I am not shure if it´s a bug but it makes no sense that behavior. I solved this problem using the second code, but I want no make sure what ís happening, Why the idx jumps at the beginning?. I am using Matlab 2020a.
clearall;
closeall;
clc;
%%
xvals = [];
beta = 3;
xold = 0.5;
% Trans
fori = 1:10000
xnew = (xold-xold^2)*beta;
xold = xnew;
end
fori=1:5
xnew = (xold-xold^2)*beta;
xold = xnew;
idx = length(xvals)+1;
fprintf("%d\t%d\n",beta,idx);
xvals(1,idx) = beta;
xvals(2,idx) = xnew;
end
Output:
3 1
3 3
3 4
3 5
3 6
clearall;
closeall;
clc;
%%
xvals = zeros(2,1);
idx = 1;
beta = 3;
xold = 0.5;
% Trans
fori = 1:10000
xnew = (xold-xold^2)*beta;
xold = xnew;
end
fori=1:5
xnew = (xold-xold^2)*beta;
xold = xnew;
fprintf("%d\t%d\n",beta,idx);
xvals(1,idx) = beta;
xvals(2,idx) = xnew;
idx = idx +1;
end
Output
3 1
3 2
3 3
3 4
3 5

Accepted Answer

Allen
Allen on 26 May 2021
Ciro,
It has to do with the way that the length function works. It will find and return the largest dimension in a 2-D array. Since you start with an empty array for xvals its initial length is 0, and after the first interation of your loop if becomes a 2x1 column vector with length 2. You xvals variable then continues to grow by 1 column each iteration of the loop. By the third iteration it is a 2x3 array and length returns 3 since the number of columns respresents the largest dimension.
xvals = [];
idx = 1;
beta = 3;
xold = 0.5;
% Trans
fori = 1:10000
xnew = (xold-xold^2)*beta;
xold = xnew;
end
fori=1:5
xnew = (xold-xold^2)*beta;
xold = xnew;
fprintf("Interations: %i,\tlength(xvals)= %i\n",i,length(xvals))
idx = length(xvals)+1;
xvals(1,idx) = beta;
xvals(2,idx) = xnew;
end
Interations: 1, length(xvals)= 0 Interations: 2, length(xvals)= 2 Interations: 3, length(xvals)= 3 Interations: 4, length(xvals)= 4 Interations: 5, length(xvals)= 5
If you are intending to focus on the size of array in a fixed dimension, you can you size instead of length .
size(xvals,1)% Returns the row size
size(xvals,2)%返回列的大小
[r,c] = size(xvals);% Returns both the row and column sizes as a 1x2 array for 2-D arrays
If you are trying to have your idx variable increase by 1 each iteration, then you should just use your loop variable, i , that is already increasing by 1.
xvals = [];
beta = 3;
xold = 0.5;
% Trans
fori = 1:10000
xnew = (xold-xold^2)*beta;
xold = xnew;
end
fori=1:5
xnew = (xold-xold^2)*beta;
xold = xnew;
fprintf("%d\t%d\n",beta,i);
xvals(1,i) = beta;
xvals(2,i) = xnew;
end

More Answers (2)

dpb
dpb on 26 May 2021
The code needed to see the problem boils down to--
xvals=[];
fori=1:5
xnew = (xold-xold^2)*beta;
xold = xnew;
idx = length(xvals)+1;
fprintf("%d\t%d\n",beta,idx);
xvals(1,idx) = beta;
xvals(2,idx) = xnew;
end
Walk through the first few iterations--
  1. -- length([]) is zero so idx=1. You then assign values to positions 1 and 2 of xvals by xvals(1,1), xvals(2,1) as idx=1
  2. length(xvals) is now 2 so idx=3. Voila! The "jump"
  3. this time you set xvals(1,3), xvals(2,3) so length(xvals) is still 3 and idx --> 4
You could have seen this if had used the debugger to set a breakpoint in your code and stepped through inspecting the results to have spotted the logic error if the "mental computer" failed to catch out the issue. It takes practice and real discipline to be able to put aside thinking the code will return what is intended/wanted instead of making sure are following the exact steps of the code as written so isn't too surprising you missed...
2 Comments
dpb
dpb on 26 May 2021
“兰gth() returns the same as size(var,1)"
不! !
length(x) returns max(size(x)) as another OP noted.
length is a very dangerous function; it really shouldn't have been introduced with the behavior it has, but it was in the original incarnation and so just can't go away.

Sign in to comment.


Jan
Jan on 26 May 2021
The code shows the expected behavior:
xvals = [];
fori=1:5
idx = length(xvals)+1;
xvals(1,idx) = rand;
xvals(2,idx) = rand;
end
In the first iteration xvals is empty, than length(xvals)+1 is 1. After setting xvals to a [2, 1] vector, its length is 2, so length(xvals)+1 is 3.
length() is a dangerous command, which causes bugs frequently. If chooses the longest dimension automagfically. If you want to measure the size of the 2nd dimension, use size(xvals, 2) instead.

Tags

s manbetx 845

Community Treasure Hunt

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

Start Hunting!