0

I have a array X=[1 2 3 1.01 2.01 4 5 1.01 3.01] I want to all index of this array are similar and difference<=0.01 in matlab answer is

    X1=[1 4 8], X2=[2 5],X3=[3 9],X4=[6],X5=[7]

many thanks

3
  • 1
    What result would you want for X = [1.00 1.01 1.02 1.03 1.04]? Commented Aug 19, 2014 at 7:34
  • I think the question is how to find indices of "unique" values where values within 0.01 of each other are considered the same. Commented Aug 19, 2014 at 7:36
  • 1
    Well, the example in the question could easily be solved with unique(round(X)). That's why the OP should clarify (a) whether the tolerance is always around integers and (b) what to do if a sequence of elements are within tolerance of their neighbours but the overall sequence isn't (see my previous comment). Commented Aug 19, 2014 at 7:48

3 Answers 3

1

Here a solution using for-loop. Not sure about efficiency though. Gonna try to find another solution as well.

X=[1 2 3 1.01 2.01 4 5 1.01 3.01]
result=cell(length(X),1);
boarder = 0.01;
for n=1:length(X)
    helper = X(n);
    Y=X;
    Y(X>helper+boarder)=0;
    Y(X<helper-boarder)=0;    
    result(n,1)={find(Y)};
end

I predefine a cellarray (result) which contains all index (for each element of X). Then I loop over the elements setting those who are outside of your boarder to 0. Last but not least I save the index to the result array.

Obviously some results are the same but this way you get also results for the case: X=[ 1.01, 1.02, 1.03, 1.04,...];

And if you want to delete those elements which are the same you could loop over your data again and get unique results.

Sign up to request clarification or add additional context in comments.

Comments

1
Y=cell(5,1)
for idx=1:numel(Y)
   Y{idx}=find(abs(X-idx)<=.2);
end

Comments

1

I think the submission "unique with tolerance" in the FileExchange is for you.

You should note, that creating the variables X1...X5 as separate variables is a bad idea and a bad practice, because this makes referencing these values in later code (which is either vectorized or loop-based) cumbersome and inefficient. More correct alternatives to storing the data are cells (like in the solution suggested by Daniel) or in structs.

Having said that, if for some reason you still want to create uniquely named variables, this is possible using a mix of the aforementioned submission (uniquetol) and eval:

[~,b,c]=uniquetol(X,0.01+eps);
for ind1 = 1:length(b)
    eval(sprintf('X%d = (find(c==X(b(%d))))'';',ind1,ind1)); 
end

3 Comments

I think you should change this answer from using eval to using a cell array. They OP may ask for individual variables but this is bad practice and should not be promoted.
I completely agree with you that this is bad practice. I have no idea why the OP wants to do it this way, but this is what was asked for.
@Dan - answer was amended to include your (justified) remarks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.