matlab gets different answers for the same code

for loop=1:10
i12=randperm(n,2);
i1=i12(1);
i2=i12(2);
% i1=2;i2=6;
Floyd(i1,i2)
Dijkstra(i1,i2)
end
The above 2 algorithms (last 2 functions) are supposed to return the same answer and they usually do. But when I run for many loops, because of the rand numbers i1, i2 (by randperm), these 2 functions get different results. Strangely when i1 and i2 are fixed and randperm is removed, these 2 function 100% return the same result. Why?!

12 Comments

What's the value of n and what's inside the two functions?
n is the total number of nodes in a graph where i look for a shortest path. the 2 functions will return a distance and route.
We need the code for them.
Do you really expect that someone could diagnose why two unfamiliar functions produce different results given the same inputs without seeing what the functions are doing? It could be because...
  • ...the function are doing different things and coincidentally have outputs that appear to be the same for some inputs.
  • ...rounding error
  • ...at least one function relies on a random process
  • ...your analysis of the results are incorrect and they do produce the same outputs
I also see that you aren't storing the outputs for each iteration and I wonder if you're just comparing the final results. The problem is obviously either with your expectations for these functions, the code within the functions, or your analysis of the results. Without a minimal working example we cannot help you.
I'm assuming the "right" and "wrong" functions are the Floyd and Dijkstra functions.
Did you write both of these functions or did you get them from somewhere?
When I run the code, on some iterations the dis1 and dis2 outputs match and sometimes they don't.
dis1-dis2
ans =
Columns 1 through 8
0 0 0 0 0 0 0.083754 0.3272
Columns 9 through 10
0.00029923 0.46701
What makes you think they should always match? I'm not going to dissect each function to identify where the algorithms bifurcate but clearly they are two different algorithms that behave slightly different for some sets of inputs.
Yes I wrote myself. When you uncomment the i1 i2 line, giving them fixed numbers rather than randomized ones, the 2 functions are exactly the same. of course you can also change i1 and i2 to any numbers. the W matrix can be randomized as well.
The code is very hard to debug because of some bad practices.
Never use global variables. Instead, pass those variables into the functions as additional inputs.
Avoid putting several executable lines of code in the same line of the file (ie: nodesSub=nodes;nodesSub(ii)=[]). It might make sense to you but will greately decreases readability when others look at your code.
Variable names such as i12 i1 i2 ii are difficult to distinguish.
When you run the code with randperm(), on each iteration the i12, i1, i2 W, and nodes variables change.
When you run with the fixed values for i1 and i2, the w and nodes variables still change but i1 and i2 do not. That's comparing apples to oranges.
Here's a list of i12 values that were produced by randperm() for 10 iterations
randPermValues = [
8 7
1 7
5 6
5 4
7 6
5 2
2 8
6 2
5 7
5 2];
They resulted in the following dis1 dis2 differences.
>> dis1-dis2
ans =
Columns 1 through 8
0 0 0.2041 0.13379 0.24726 0.019765 0.40222 0
Columns 9 through 10
0 0
Now run those same, hard-coded values.
clear;clc;
global process% print intermediate computations
process=1*0;
n=8;% # nodes
nodes=1:n;% imtermediate nodes
randPermValues = [
8 7
1 7
5 6
5 4
7 6
5 2
2 8
6 2
5 7
5 2];
for loop=1:10
% i12=randperm(n,2);
i12 = randPermValues(loop,:);
i1=i12(1);
i2=i12(2);% start and end
% i1=2;i2=6;
global W% weight matrix
W=rand(n);
W=W-diag(diag(W));% Wii=0
% remove start and end from nodes for my code
for i=1:length(nodes)
if nodes(i)==i1
nodes(i)=[];break;
end
end
for i=1:length(nodes)
if nodes(i)==i2
nodes(i)=[];break;
end
end
[dis1(loop),route1{loop}]=wrong(i1,nodes,i2)
[dis2(loop),route2{loop}]=right(i1,i2)
end
And you'll see that there are still differences
dis1-dis2
ans =
Columns 1 through 8
0 0 0 0 0.1659 0 0 0
Columns 9 through 10
0.39936 0
With fixed values for i1 and i2, nodes doesn't change. However, suppose on iteration number i the i1 and i2 values are 5 and 6 create node values of [2 3 4] (I'm making these numbers up). That doesn't mean that every time i1 and i2 are 5 and 6, the nodes will always be [2 3 4].
Can someone post an official Answer for this below in the official Answer section?
"my 'nodes' is always 1:n subtracted by i1 and i2"
No, that's not true. Run the randperm() version and print out the results of nodes.
nodes =
1 2 5 6 7 8
nodes =
2 5 6 7
nodes =
2 6 7
nodes =
6 7
nodes =
6 7
nodes =
6
The nodes are always the same when the i1 and i2 are constant but when you use randperm(), i1 and i2 are not constant.
thx a lot adam! i didnt notice this obvious mistake. bug found!
The original question copied here, in case the OP deletes it like they have done with other questions:
"matlab gets different answers for the same code"
for loop=1:10
i12=randperm(n,2);
i1=i12(1);
i2=i12(2);
% i1=2;i2=6;
Floyd(i1,i2)
Dijkstra(i1,i2)
end
The above 2 algorithms (last 2 functions) are supposed to return the same answer and they usually do. But when I run for many loops, because of the rand numbers i1, i2 (by randperm), these 2 functions get different results. Strangely when i1 and i2 are fixed and randperm is removed, these 2 function 100% return the same result. Why?!

Sign in to comment.

 Accepted Answer

Summary of comments under the question
The two functions being compared aren't necessarily doing the same thing though, with some sets of inputs, they do produce the same results.
Regarding the tests between randperm() and hard-coded, constant values, those values aren't the only variable that affects the outputs. Some reasons this may have been difficult to detect include the use of global variables, variable names that are difficult to distinguish, and multiple lines of code on the same line within the file.

6 Comments

thanks a lot. but what's wrong with using global variables?
"thanks a lot. but what's wrong with using global variables?"
The use of global variables requires a high level of responsibility and skill which is why beginners should never use global variables. It's rare that a global variable is needed so when we see code with global variables it's a good sign that the person is a noobie.
If you need to pass a value to another function, pass it as an input.
thx. but the link you provide doesn't say anything too bad about global variables. i have never trouble using them. any other common cons?
The last large project I worked on, I had to spend several weeks rewriting the code to locate all the places I was reading and writing global variables and figuring out why an incompatibility was showing up. I ended up using accessor routines -- which still had the effect of changing global state, but in a more detectable way (and the code was made more disciplined about not requesting variables it did not strictly need.)
Global variables can be quite hard to debug with.
i have never trouble using them.
My father, who taught electrical and electronics, made sure I knew about turning devices off, and about grounding, and about always unplugging equipment you were working on ("just to be sure"), and I made sure to do all of that. Now, our clothes dryer had the tendency to melt one of the internal junctions, and he showed me how to fix it, and I always took all those precautions, along with being very careful in case the floor was wet. Nothing happened while he was still with us, and in the years later when I had to repair the dryer, nothing happened but I still made sure to take all the precautions and check them twice, to make sure that nothing would happen. All was well (other than the repair being a nuisance), and if someone else had done the same repair and not been as rigorous in precautions, chances are nothing would have happened to them.
Until, that is, the year when I took all those precautions, but got a rather nasty shock. This was 220 volt, 30 amp equipment. I couldn't move my hand away immediately -- AC locks your hand muscles. I thought I was probably done for.
Later, I checked and confirmed that I had taken all of the regular precautions.
What had happened? I'm not sure, but I realized that my father had forgotten to advise me that larger motors often have large capacitors that might need to be discharged.
Yes, when you use global variables you might never have had trouble using them. So far. But as professional programmers with decades of experience, we tell you that we have seen many a person laid low by global variables. There can be uses for global variables, but the people who get less afflicted by the problems with global, are the people who use the programming equivalents of grounding straps and shutting down the fuse box, taking deliberate preventitive steps to reduce the opportunity for problems.
Very well-grounded advice!

Sign in to comment.

More Answers (0)

Categories

Find more on Programming in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!