Array idx bug when resizing it

2 visualizaciones (últimos 30 días)
Ciro Bermudez
Ciro Bermudez el 26 de Mayo de 2021
Comentada: dpb el 26 de Mayo de 2021
I am making the code to plot a bifurcation diagram, 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.
clear all;
close all;
clc;
%%
xvals = [];
beta = 3;
xold = 0.5;
% Trans
for i = 1:10000
xnew = (xold-xold^2)*beta;
xold = xnew;
end
for i=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
clear all;
close all;
clc;
%%
xvals = zeros(2,1);
idx = 1;
beta = 3;
xold = 0.5;
% Trans
for i = 1:10000
xnew = (xold-xold^2)*beta;
xold = xnew;
end
for i=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

Respuesta aceptada

Allen
Allen el 26 de Mayo de 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
for i = 1:10000
xnew = (xold-xold^2)*beta;
xold = xnew;
end
for i=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) % Returns the column size
[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
for i = 1:10000
xnew = (xold-xold^2)*beta;
xold = xnew;
end
for i=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

Más respuestas (2)

dpb
dpb el 26 de Mayo de 2021
The code needed to see the problem boils down to--
xvals=[];
for i=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 comentarios
Ciro Bermudez
Ciro Bermudez el 26 de Mayo de 2021
Thank you, now I see where the error is, length() returns the same as size(var,1), and what I really what to change is the columns length not the rows, if I change
idx = length(xvals)+1;
for
idx = size(xvals,2)+1;
the problem is fixed, Thank you very much, I really appreciate how quickly you answered.
dpb
dpb el 26 de Mayo de 2021
" length() returns the same as size(var,1)"
NO!!!!
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.

Iniciar sesión para comentar.


Jan
Jan el 26 de Mayo de 2021
The code shows the expected behavior:
xvals = [];
for i=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.

Categorías

Más información sobre Resizing and Reshaping Matrices en Help Center y File Exchange.

Etiquetas

Productos

Community Treasure Hunt

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

Start Hunting!

Translated by