SAVE MATRIX WHILE I SHOULD GET 121 BY 10 AS THE NO OF ITERATIONS SHOULD BE 10 ONLY NOT 11

2 次查看(过去 30 天)
I have time iteration loop and I creat saves matrix that should be in dimension of 121 by 10
and I used r symbol to store the matrix column, I get 121 by 11 SAVE MATRIX WHILE I SHOULD GET 121 BY 10 AS THE NO OF ITERATIONS SHOULD BE 10 ONLY NOT 11
N_grids=121
ti=0
dt=0.1
tf=1
Psave=ones(N_grids,(tf-ti)/dt) % store matrix
t=ti % initial time
r=1; % indexing for store matrix
While t < tf
A= % equation of calculation
end
P=PCurrent
Psave(:,r)=Pcurrent
t=ti+dt
r=r+1
end
  2 个评论
AndresVar
AndresVar 2022-2-17
编辑:AndresVar 2022-2-17
this code doesn't run, it has missing variables. Edit your question so it runs.
btw your loop runs 11 times because of numerical error, see this
a = 0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1
a = 1.0000
a==1
ans = logical
0
a-1
ans = -1.1102e-16
Change it to a for loop or account for this very tiny difference.

请先登录,再进行评论。

回答(2 个)

Voss
Voss 2022-2-17
On the last iteration, t is not exactly equal to tf; it is very close but still a little less:
ti=0;
dt=0.1;
tf=1;
t=ti; % initial time
while t < tf
disp(sprintf('Current time: %g, Time remaining: %g',t,tf-t));
t=t+dt;
end
Current time: 0, Time remaining: 1 Current time: 0.1, Time remaining: 0.9 Current time: 0.2, Time remaining: 0.8 Current time: 0.3, Time remaining: 0.7 Current time: 0.4, Time remaining: 0.6 Current time: 0.5, Time remaining: 0.5 Current time: 0.6, Time remaining: 0.4 Current time: 0.7, Time remaining: 0.3 Current time: 0.8, Time remaining: 0.2 Current time: 0.9, Time remaining: 0.1 Current time: 1, Time remaining: 1.11022e-16
To correct for this, you could use a small threshold to compare with; something like this:
ti=0;
dt=0.1;
tf=1;
t=ti; % initial time
while t < tf - 1e-6
disp(sprintf('Current time: %g, Time remaining: %g',t,tf-t));
t=t+dt;
end
Current time: 0, Time remaining: 1 Current time: 0.1, Time remaining: 0.9 Current time: 0.2, Time remaining: 0.8 Current time: 0.3, Time remaining: 0.7 Current time: 0.4, Time remaining: 0.6 Current time: 0.5, Time remaining: 0.5 Current time: 0.6, Time remaining: 0.4 Current time: 0.7, Time remaining: 0.3 Current time: 0.8, Time remaining: 0.2 Current time: 0.9, Time remaining: 0.1
But since the time-step never changes in this case it's probably better to use a for loop instead of a while loop.

Walter Roberson
Walter Roberson 2022-2-17
format long g
ti=0
ti =
0
dt=0.1
dt =
0.1
tf=1
tf =
1
t = ti;
counter = 0;
while t < tf
t = t + dt;
counter = counter + 1;
[t, counter*dt - t]
end
ans = 1×2
0.1 0
ans = 1×2
0.2 0
ans = 1×2
0.3 0
ans = 1×2
0.4 0
ans = 1×2
0.5 0
ans = 1×2
0.6 1.11022302462516e-16
ans = 1×2
0.7 1.11022302462516e-16
ans = 1×2
0.8 1.11022302462516e-16
ans = 1×2
0.9 1.11022302462516e-16
ans = 1×2
1 1.11022302462516e-16
ans = 1×2
1.1 2.22044604925031e-16
What does this tell you? It tells you that if you start from 0 and add 0.1 each time, then after 1 iterations, you have not reached 1, you have reached 1.11022302462516e-16 less than 1. Because you are using a strict < test rathern than testing whether the value is "close to" the target, this causes you to go one iteration more than you are expecting.
Why does adding 0.1 repeatedly not give you exactly 1 ? It is because 0.1 exactly cannot be exactly represented in binary floating point (with any finite number of digits.) The closest representable number happens to be just slightly less than 1/10 , so when you add the number to itself repeatedly 10 times, you end up with a result that is just a little less than 1 .
The mathematical reason that 1/10 exactly cannot be represented in finite binary floating point is the same reason why 1/3 exactly cannot be represented in finite decimal floating point. Consider a system with 3 digit decimal precision, which would represent 1/3 as 0.333 . The sequence of additions would go 0, 0.333, 0.333+0.333 --> 0.666, 0.666+0.333 -> 0.999 . Now you have added "1/3" three times but you did not get exactly 1. And the same problem happens in a decimal system if you were using 100 decimal digits: add the closest representation of 1/3 three times and the final result would be all 9's rather than 1.
It is, in other words, not a MATLAB "bug": it is a problem inherent in any system that uses a finite number of digits in any fixed numeric base.

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

标签

产品


版本

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by