1

i have a matrix B{1} =[1.1 1.1 1.0 ; 0.8 0.9 1.2 ; 0.9 0.9 1.5] I have found that the overall median of the matrix is 1.0.

Next i want to go through every element in the matrix and compare it with the median. If the element exceeds the error threshold value of 0.1, the element will be replaced by zero. If the element is equal or lesser than 0.1, the element value will remain.

After going through the coding below, i am expecting my end result of B{1} to be [1.1 1.1 1.0 ; 0.0 0.9 0.0 ; 0.9 0.9 0.0].

However the output of the coding below gives B{1}=[ 0.0 0.0 1.0 ; 0.0 0.9 0.0 ; 0.9 0.9 0.0]

for x=1:9
matrix=B{1};
excess = abs(minus(matrix(x),1.0)) 
if excess > 0.1
matrix(x)=0;
B{1}=matrix;
end 
end

Any idea where is the mistake(s) in the coding?

Amilia
  • 25
  • 2
  • It's a case of precision issue, look here for another example and some explanation on this - http://stackoverflow.com/questions/686439/why-is-24-0000-not-equal-to-24-0000-in-matlab – Divakar Apr 01 '14 at 05:29
  • Another one, probably closer to your case - http://stackoverflow.com/questions/13699596/is-this-a-matlab-bug-do-you-have-the-same-issue – Divakar Apr 01 '14 at 05:37

1 Answers1

1

You are running into precision issue, which can be avoided by adding a little tolerance into it. With that change, you can have a vectorized solution to this -

B{1} =[1.1 1.1 1.0 ; 0.8 0.9 1.2 ; 0.9 0.9 1.5] 
matrix=B{1};
TOL = 0.001;%%// Tolerance to account for precision issue
matrix(abs(bsxfun(@minus,matrix,median(matrix(:))))>0.1+TOL)=0;
B{1} = matrix;

In your code, you could have done the same with this -

TOL = 0.001;%%// Tolerance to account for precision issue
excess = abs(minus(matrix(x),1.0+TOL)) 

Edit 1: You can add a matrix dependent tolerance to it, by using this (thanks to @bdecaf on this) -

TOL = max(eps(matrix(:)))
Divakar
  • 218,885
  • 19
  • 262
  • 358
  • thank you @Divakar for the suggestions:) the above code still produce the same output. will look into the other examples to correct the precision issues. – Amilia Apr 01 '14 at 06:11
  • 1
    @Amilia I could suggest something on that. Why not add a little tolerance value of say 0.001 into the threshold value. With that, the code would become - `matrix(abs(bsxfun(@minus,matrix,median(matrix(:))))>0.1+0.001)=0`. Try it out if it works for you. I think you can add as little as `1e-15` as the tolerance. – Divakar Apr 01 '14 at 06:24
  • yea,it works. The output is as what i am expecting, with the input of the tolerance to the threshold value. Thanks a lot @Divakar :) – Amilia Apr 01 '14 at 06:40
  • Just want to add that to obtain a reasonable value for the tolerance the `eps` function can give you the size of your least significant bit when you call it with an input - like `eps(matrix(x))`. – bdecaf Apr 01 '14 at 08:23
  • @Divakar okay noted:) – Amilia Apr 01 '14 at 09:07
  • @Amilia Check out Edit -1, for that. – Divakar Apr 01 '14 at 09:13
  • Note that using `eps` might give a false sense of security. Especially if there are multiple consecutive operations it may not be sufficient. Personally I will always use `10*eps`, there are still no guarantees but it should be quite robust. – Dennis Jaheruddin Apr 01 '14 at 11:41
  • @DennisJaheruddin Why did you choose the multiplying factor of `10` here? Any logical reason for that? – Divakar Apr 01 '14 at 11:47
  • 1
    @Divakar There is not a reason why it is 10, opposed to 5 or 20. I just chose to go up 1 order of magnitude as some people choose 2, which may still cause you to run into problems in practice. On the other hand some might choose 1000, which may lead to different kinds of problems. This is mostly just a matter of personal preference. – Dennis Jaheruddin Apr 01 '14 at 12:41