Persistent output problems with a for loop block!

1 view (last 30 days)
Hello everyone. I was trying to run a certain code block:
clear;
E1 = 70e9;
E2 = E1/2;
E3 = E1/4;
t = 0.0125;
L1 = 0.1;
L2 = 0.3;
L3 = 0.2;
P1 = 50e3;
P2 = 20e3;
P3 = 30e3;
w1 = 0.01;
w2 = 0.025;
el_L=0.1;
%BAR - 1
B1_LWN=(L2/el_L)+1;
%BAR - 2
B2_LWN=(L2/el_L)+1;
%BAR - 3
B3_LWN=(L1/el_L)+1;
%BAR - 4
B4_LWN=(L3/el_L)+1;
totalNodes=B1_LWN+B2_LWN+B3_LWN+B4_LWN-3;
x=zeros(1,totalNodes);
y=zeros(1,totalNodes);
NWL=[B1_LWN,B2_LWN,B3_LWN,B4_LWN; %number of length-wise nodes of beams
L2,L2,L1,L3; % length of beams in (m)
0,0,0.3,0.4; % starting x coordinate of beam
0.3,0.3,0.4,0.6; % ending x coordinate of beam
0.005,0.02,0.0125,0.0125; ]; % y coordinate of element cg
%BEAM NODE COORDINATES
node=0;
for k=1:4
inc=NWL(2,k)/((NWL(1,k)-1));
Xcoords=NWL(3,k):inc:NWL(4,k);
for i=1:(NWL(1,k)-1)
node = node + 1;
if(k==4&&i==NWL(1,4)-1)
x(1,node) = Xcoords(i);
y(1,node) = NWL(5,k);
node=node+1;
x(1,node) = Xcoords(i+1);
y(1,node) = NWL(5,k);
else
x(1,node) = Xcoords(i); % nodal x-position
y(1,node) = NWL(5,k); % nodal y-position
end
end
end
So when I run the code I have no syntax errors. However, if I replace the values of the 1st and 2nd row of matrix NWL with the SAME constant values (i.e: B1_LWN replaced with 4 as when you calculate it's value from the %BAR-1 commented section, you end up getting 4) for all of the 1st and 2nd rows, I get an entirely different output for vectors x and y!!! Can someone explain why this is happening? It makes no sense at all. I tried everything. Thanks.
  1 Comment
Guillaume
Guillaume on 21 Sep 2017
Rather than adding a blank line between each line of code which does not make it any easier to read, just copy/paste your code then press the {} Code button (which will just put two spaces at the start of each line).

Sign in to comment.

Answers (2)

Tim Berk
Tim Berk on 21 Sep 2017
That's crazy!!
The problem is caused by numerical precision. When Matlab calculates 0.3/0.1, this is not exactly 3. I'm sure someone else can explain why, but apparently Matlab estimates divisions. Try
isequal(0.3/0.1,3)
or even better
0.3/0.1-3
(The latter does not return zero).
A workaround to solve your problem is to round the values in B1_LWN, B2_LWN etc. Because
isequal(round(0.3/0.1),3)
does return 1.
  5 Comments
Tim Berk
Tim Berk on 21 Sep 2017
Edited: Tim Berk on 21 Sep 2017
Thanks for pointing that out. I thought it was best to (even with my limited knowledge) give a solution for OP. Using round in this particular case actually solves their particular problem.
OP is comparing the output of lets say 0.3/0.1 to integers. In simplified form:
for i = 1:N
if i==0.3/0.1
@Jose, your version would be (as I understand it)
if i==(0.3/0.1+eps(0.3/0.1))
@Guillaume, your version (as I understand it)
if abs(i-0.3/0.1)<1e-15
Would you use this when simply comparing (what are supposed to be) integers? Isn't round the best way to go to the closest integer? Even after all your explanations (for this particular problem) I would still use round as it you can actually take this out of the loop, i.e.
B = round(0.3/0.1);
for i = 1:N
if i==B
@Stephen, what would you use? Apparently you know a lot about this but I didn't see a solution.
José-Luis
José-Luis on 21 Sep 2017
Edited: José-Luis on 21 Sep 2017
I would use:
abs(3 - 0.3/0.1) < eps(3)
which is rather stringent.
Using round() is a bad idea. Please refer to the links Stephen posted. However much you say that they are supposed to be integers, they are not. They are doubles.
You can probably cross a country road without looking left and right and get away with it most of the time. Until one day when that becomes a one way ticket to meet your maker.

Sign in to comment.


Rahul Pillai
Rahul Pillai on 21 Sep 2017
Hello everyone. Thank you for all your suggestions. I worked this solution out last night because I figured it was a precision problem that goes undetected to the human eye! I simply used the round() function while performing the division. It worked :)
  1 Comment
José-Luis
José-Luis on 21 Sep 2017
It might have worked this time but it will come back and bite you eventually. The better approach is to use a tolerance.
That being said, please accept the answer that best solves your problem.

Sign in to comment.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!