Indexing Arrays within a for loop

Please help. I am trying to index values of the Vc array at a specific point that correspond to the potion in the t array. The t and Vc arrays are a (size) long and will be remade everytime for 100 iterations to fill up the A array.
%% Creating Initial Population
A = zeros(1,100);
R = zeros(1,100);
C = zeros(1,100);
Vs = zeros(1,100);
tc = zeros(1,100);
dt=0.01;
t=0:dt:10;
n=size(t);
Vc=zeros(1,n(2));
Vc(1)=0;
A(1)=0;
for i = 1:1:100
R= 20000 + (50000-20000)*rand(1);
C= 0.0001 +(0.001-0.0001)*rand(1);
Vs= 5 +(20-5)*rand(1);
tc= 1+(8-2)*rand(1);
dt=0.01;
t=0:dt:10;
n=size(t);
Vc=zeros(1,n(2));
Vc(1)=0;
A(1)=0;
%% 4 Euler's Charging and Discharging
limit = round(tc/dt);
for i=2:limit+1
Vc(i)=Vc(i-1)+(eps/(R*C)-Vc(i-1)/(R*C))*dt;
end
%Discharge
for i=(limit+2):n(2)
Vc(i)=Vc(i-1)+(-Vc(i-1)/(R*C))*dt;
end
%% create below
%% the index values of the Vc array at a specific index that corresponds to the t array
%% the t and Vc arrays are fixed numbers long and will be remade everytime for 100 iterations in order to fill up the A Array
A(i+1) = ( Vc(t=0)-0)^2 + (Vc(t=2)-3.27)^2 + (Vc(t=4)-5.79)^2 + (Vc(t=6)-7.70)^2 + (Vc(t=8)-6.64)^2 + (Vc(t=10)-5.09)^2;
end

2 Kommentare

KSSV
KSSV am 18 Mär. 2021
What problem you have with the give code? What is the question?
Christopher Jarrett
Christopher Jarrett am 18 Mär. 2021
Using the for loop which computates the random varables R,Vs,tc,C to generate the Vc, I need to create the 100 variable long array A. I don't know why the A is coming out to be a single scalar of 173 and not an array with a bunch of different values that would correspond to the randomness of the 4 random variables.
This is part of an optimization problem where the best variables need to be sorted and selected to eventually get an A value that is as close to zero as possible. Help is appreciated.

Melden Sie sich an, um zu kommentieren.

Antworten (1)

Walter Roberson
Walter Roberson am 18 Mär. 2021

0 Stimmen

%% Creating Initial Population
A = zeros(1,100);
R = zeros(1,100);
C = zeros(1,100);
Vs = zeros(1,100);
tc = zeros(1,100);
dt=0.01;
t=0:dt:10;
n=size(t);
Vc=zeros(1,n(2));
Vc(1)=0;
A(1)=0;
for i = 1:1:100
R= 20000 + (50000-20000)*rand(1);
C= 0.0001 +(0.001-0.0001)*rand(1);
Vs= 5 +(20-5)*rand(1);
tc= 1+(8-2)*rand(1);
dt=0.01;
t=0:dt:10;
n=size(t);
Vc=zeros(1,n(2));
Vc(1)=0;
A(1)=0;
%% 4 Euler's Charging and Discharging
limit = round(tc/dt);
for i=2:limit+1
Vc(i)=Vc(i-1)+(eps/(R*C)-Vc(i-1)/(R*C))*dt;
end
%Discharge
for i=(limit+2):n(2)
Vc(i)=Vc(i-1)+(-Vc(i-1)/(R*C))*dt;
end
%% create below
%% the index values of the Vc array at a specific index that corresponds to the t array
%% the t and Vc arrays are fixed numbers long and will be remade everytime for 100 iterations in order to fill up the A Array
A(i+1) = ( Vc(t==0)-0)^2 + (Vc(t==2)-3.27)^2 + (Vc(t==4)-5.79)^2 + (Vc(t==6)-7.70)^2 + (Vc(t==8)-6.64)^2 + (Vc(t==10)-5.09)^2;
end
nnz(A)
ans = 1
A(i+1)
ans = 173.5047

4 Kommentare

What happened is that you accidentally invoked the new (R2021a) syntax for using named parameters, such as
plot(rand(1,20),color='r')
Apparently it converts into strings
Test = @(varargin) celldisp(varargin)
Test = function_handle with value:
@(varargin)celldisp(varargin)
Test(t=0)
varargin{1} = t varargin{2} = 0
I don't know why the A is coming out to be a single scalar of 173
You have
for i = 1:1:100
some code #1
for i=2:limit+1
some code #2
end
for i=(limit+2):n(2)
some code #3
end
A(i+1) = ( Vc(t==0)-0)^2 + (Vc(t==2)-3.27)^2 + (Vc(t==4)-5.79)^2 + (Vc(t==6)-7.70)^2 + (Vc(t==8)-6.64)^2 + (Vc(t==10)-5.09)^2;
end
Notice that inside your for i you have two further for i . You are modifying the value of the loop control variable i within your outer for i loop.
MATLAB keeps internal variables for each for loop that it initializes when you start the loop, variables that record the start and increment and final value, and an internal variable to hold the current value. At the beginning of any given iteration of the for loop, it increments the internal current value of the loop control variable, and compares it to the endpoint, and if the termination condition has not been reached yet, then it copies the internal current value to the public version of the loop control variable overwriting whatever value it had . But if the termination condition has been reached, then the loop is exited leaving the public variable at whatever it last had .
So if you had
for i = 1 : 2
i = i^7 + 3
end
then it initializes
public i = []
internal i = 1
internal i increment = 1
internal i terminal = 2
and then it begins the loop
beginning of loop:
if internal i > internal i termimal
exit loop
else
public i = internal i %hidden
public i = (public i)^2 + 3 %body of the loop
internal i = internal i + internal i increment %hidden
go back to begining of loop
end
so
public i = []
internal i = 1
internal i increment = 1
internal i terminal = 2
test internal i (1) > internal i terminal (2) --> false so use else
public i = internal i -> public i = 1
public i = (public i)^2 + 3-> public i = 1^2 + 3 -> public i = 4
internal i = internal i (1) + internal i increment (1) -> internal i = 2
go back to beginning of loop
test internal i (2) > internal i terminal (2) --> false so use else
public i = internal i -> public i = 2 (overwriting the 4 as if the 4 had not happened!)
public i = (public i)^2 + 3-> public i = 2^2 + 3 -> public i = 7
internal i = internal i (2) + internal i increment (1) -> internal i = 3
go back to beginning of loop
test internal i (3) > internal i terminal (2) --> true, so exit loop
Notice how the public i is left at 7, the last value it was assigned inside the loop.
And so in your code, with your nested for i loops, you have
for i = 1:1:100
%i starts with 1 and will go through 2, 3, ... 100
some code #1
for i=2:limit+1
%public i will go through 2... limit+1
some code #2
end
%i will now be the last value it was assigned in this inner loop, so
%public i wil be limit+1
for i=(limit+2):n(2)
public i goes through limit+2..n(2)
some code #3
end
%public i is now n(2)... unless n(2) was greater than limit+2 in which
%case public i will now be []
A(i+1) = ( Vc(t==0)-0)^2 + (Vc(t==2)-3.27)^2 + (Vc(t==4)-5.79)^2 + (Vc(t==6)-7.70)^2 + (Vc(t==8)-6.64)^2 + (Vc(t==10)-5.09)^2;
At this point, the i+1 on the left hand side is not the value of i from the outer loop, because you have written to i inside the outer loop. The i+1 on the left side will now be either [] or n(2)+1, a constant relative to the loop. So the same output location will be written to for each iteration of the outer loop.
Lesson of the day:
Use meaningful loop control variable names so that you do not get confused about which variable means what. Or at the very least, make sure that you do not use the same loop control variable name for loops at different nesting depths.
Christopher Jarrett
Christopher Jarrett am 21 Mär. 2021
Right. Also, I didn't properly debug before posting this question.I tried using J for the 100 iter loop instead of i which (you pointed out) is iterating the inner loops but I still get the same problem. Just an 100 long array with 173.5 as the last value. Even after the changes, I'm still doing something wrong.
format long g
%% Creating Initial Population
A = zeros(1,100);
R = zeros(1,100);
C = zeros(1,100);
Vs = zeros(1,100);
tc = zeros(1,100);
dt=0.01;
t=0:dt:10;
n=size(t);
Vc=zeros(1,n(2));
Vc(1)=0;
A(1)=0;
for i = 1:1:100
R= 20000 + (50000-20000)*rand(1);
C= 0.0001 +(0.001-0.0001)*rand(1);
Vs= 5 +(20-5)*rand(1);
tc= 1+(8-2)*rand(1);
dt=0.01;
t=0:dt:10;
n=size(t);
Vc=zeros(1,n(2));
Vc(1)=0;
A(1)=0;
%% 4 Euler's Charging and Discharging
limit = round(tc/dt);
for j=2:limit+1
Vc(j)=Vc(j-1)+(eps/(R*C)-Vc(j-1)/(R*C))*dt;
end
%Discharge
for j=(limit+2):n(2)
Vc(j)=Vc(j-1)+(-Vc(j-1)/(R*C))*dt;
end
%% create below
%% the index values of the Vc array at a specific index that corresponds to the t array
%% the t and Vc arrays are fixed numbers long and will be remade everytime for 100 iterations in order to fill up the A Array
A(i+1) = ( Vc(t==0)-0)^2 + (Vc(t==2)-3.27)^2 + (Vc(t==4)-5.79)^2 + (Vc(t==6)-7.70)^2 + (Vc(t==8)-6.64)^2 + (Vc(t==10)-5.09)^2;
end
nnz(A)
ans =
100
A(1:10)
ans = 1×10
0 173.5047 173.5047 173.5047 173.5047 173.5047 173.5047 173.5047 173.5047 173.5047
With the simple fix of the loop variable names, you no longer get the 173.whatever only as the last entry: you now get it as all entries except the first.
Vc(1:10)
ans = 1×10
0 4.8145595822274e-20 9.62807523078306e-20 1.44405471720216e-19 1.92519756322483e-19 2.40623608377198e-19 2.88717030146434e-19 3.36800023891774e-19 3.84872591874309e-19 4.32934736354643e-19
max(Vc)
ans =
2.62425694204567e-17
Observe that your Vc values are tiny. With them being so tiny, when you do the (Vc(t==2)-3.27) and so on, they are round-off error compared to the value you are subtracting, so they are effectively all 0, and therefore all of the results will be the same to within round-off error.
max(diff(A(2:end)))
ans =
0

Melden Sie sich an, um zu kommentieren.

Kategorien

Produkte

Version

R2020b

Tags

Gefragt:

am 18 Mär. 2021

Kommentiert:

am 21 Mär. 2021

Community Treasure Hunt

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

Start Hunting!

Translated by