Weird result when using unique in a .m function file

I can't seem to figure out what is going on here. I'm trying to git rid of duplicate rows by using unique. At first I made a separate .m file called dup_remove.m that contained the following code
%function [dupRowValues]=dup_remove(p)
p = [-24.7697910000000,-15.8191235000000;-20.6771670000000,-3.54125200000000;-12.6771670000000,20.4587480000000;-20.6771670000000,-3.54125200000000;4.32283300000000,-1.04125200000000;-12.6771670000000,20.4587480000000;4.32283300000000,-1.04125200000000;13.0196582500000,-12.0401785500000;-11.9803417500000,-14.5401785500000;13.0196582500000,-12.0401785500000;-11.9803417500000,-14.5401785500000];
[up,I,J] = unique(p, 'rows', 'first');
ixDupRows = intersect(1:size(p,1), I);
dupRowValues = p(ixDupRows,:);
I get what I was expecting:
dupRowValues =
-24.7698 -15.8191
-20.6772 -3.5413
-12.6772 20.4587
4.3228 -1.0413
13.0197 -12.0402
-11.9803 -14.5402
So I figured that it should still work with the function excepting an input "p". So I uncommented the function, commented the matrix defining "p", and saved the file. I then went to my main program and defined p with the same values and called [dupRowValues]=dup_remove(p). Here is what i get:
dupRowValues =
-24.7698 -15.8191
-20.6772 -3.5413
-12.6772 20.4587
-20.6772 -3.5413
4.3228 -1.0413
4.3228 -1.0413
13.0197 -12.0402
-11.9803 -14.5402
-11.9803 -14.5402
How is this possible? For some reason the indexes in I and J are different. I also do not use up, I, or J anywhere else in the program
dup_remove.m
I =
1
2
3
9
5
8
J =
1
2
3
2
5
3
5
6
4
6
4
main function calling dup_remove.m with input p
I =
1
2
4
3
11
9
7
5
8
J =
1
2
4
3
8
4
7
9
6
9
5
Does anyone know what is going on? I do not see anything wrong with calling dup_remove.m.

Answers (1)

I get the same values no matter whether it's a script or a function. Here's code for your second case (my "test2.m"):
function test2
clc;
format compact;
workspace;
p = [-24.7697910000000,-15.8191235000000;-20.6771670000000,-3.54125200000000;-12.6771670000000,20.4587480000000;-20.6771670000000,-3.54125200000000;4.32283300000000,-1.04125200000000;-12.6771670000000,20.4587480000000;4.32283300000000,-1.04125200000000;13.0196582500000,-12.0401785500000;-11.9803417500000,-14.5401785500000;13.0196582500000,-12.0401785500000;-11.9803417500000,-14.5401785500000];
[dupRowValues] = dup_remove(p)
function [dupRowValues] = dup_remove(p)
% p = [-24.7697910000000,-15.8191235000000;-20.6771670000000,-3.54125200000000;-12.6771670000000,20.4587480000000;-20.6771670000000,-3.54125200000000;4.32283300000000,-1.04125200000000;-12.6771670000000,20.4587480000000;4.32283300000000,-1.04125200000000;13.0196582500000,-12.0401785500000;-11.9803417500000,-14.5401785500000;13.0196582500000,-12.0401785500000;-11.9803417500000,-14.5401785500000];
[up,I,J] = unique(p, 'rows', 'first');
ixDupRows = intersect(1:size(p,1), I);
dupRowValues = p(ixDupRows,:)
Like I said, the above code gives the same as if you hard coded in p and ran it as a script - no repeated rows like you showed.
If you're passing in p, I suspect that your numbers aren't equal out to the zillionth decimal place, and then perhaps you might be running into the issue of comparing floating point numbers like is discussed in the FAQ: http://matlab.wikia.com/wiki/FAQ#Why_is_0.3_-_0.2_-_0.1_.28or_similar.29_not_equal_to_zero.3F

8 Comments

What values did you get?
Same as you did:
-24.7698 -15.8191
-20.6772 -3.5413
-12.6772 20.4587
4.3228 -1.0413
13.0197 -12.0402
-11.9803 -14.5402
Ok, now this really baffles me. I even went through the trouble of making nested loops to get what I needed (which I did). But when I tried this new function (with input p) it still didn't work. Again when I hard-coded p, it worked. I have format compact in there as well. If I attached my code, would you care to take a look at it? Maybe you can see what I'm missing.
I did run your code, didn't I? I copied and pasted from above. Where did you "attach" it?
I still think it's because your numbers aren't the same. Did you ever read the FAQ like I suggested? They ARE all unique but you can't see enough decimal places to realize that. Try issuing "format long" to see if the difference become apparent.
The code I supplied was only a small portion of what I have on my end. I did read the FAQ but when I change the format to long it had no effect. I'll include a link to where you can download a zip file with the files and a details.txt file for a summary of how the functions work. You don't think you need to know all the details to understand how the stuff is calculated but if you do I can answer any questions. Thanks for helping me with this.
http://www.mediafire.com/?sxj6h6q8l7nxcno
What is the main m-file to run? Which one starts everything, and will demonstrate the problem?
The dup_remove you uploaded is not the same as what you gave here. For example, there is no call to unique() or intersect. Moreover, it has this line in it:
if (L1 == L2) == true
which the FAQ specifically recommends against doing for floating point values. Recall, this is what it says:
% instead of a == b
% use:
areEssentiallyEqual = abs(a-b) < tol
% for some small value of tol relative to a and b
% perhaps defined using eps(a) and/or eps(b)
You are not doing that. Why not are you not heeding its warning and taking corrective action?
That was an earlier attempt that I forgot to comment out. The comment out stuff under method 1 is what I posted. the main m-file to run is path_generation.m.

Sign in to comment.

Categories

Asked:

on 14 Apr 2012

Community Treasure Hunt

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

Start Hunting!