1

When I search for a floating point (decimal) number within a matrix in MATLAB, it does not find it even though it should be there. Specifically, I need to find a number, say yy = 0.9600, in the matrices X and Y but MATLAB does not find them. How to go around this problem?

A = reshape(1:10000,100,100).'; %'
p = size(A,1);
B = zeros(p,p);
[X,Y] = meshgrid(0:p-1,0:p-1); X = X ./ p; Y = Y ./ p;
X = round(X*10000) / 10000;
Y = round(Y*10000) / 10000;
Y = flipud(Y);
for i=1:p,
    for j=1:p,
        x = X(j,i);
        y = Y(j,i);  
        xx = mod((x+y),1);
        yy = mod((x+2*y),1);
        [r, c] = find(X==xx);     %// NOT FOUND
        [rr, cc] = find(Y==yy);   %// "
        a = A(j,i);
        B(rr(1),c(1)) = a;
    end
end
chappjc
  • 30,359
  • 6
  • 75
  • 132
  • How sure are you that there is that exact number and that it's not a rounding error? I suggest that you apply your rounding to `xx` as well... – Dan Jul 10 '14 at 11:54
  • It looks like you're trying to transform an image. This is the wrong approach for such a problem. Can you describe your problem to get a few suggestion on a better approach? – Peter Jul 10 '14 at 13:03
  • It is very hard to describe it if you have not come across chaotic mapping. It would make more sense if you looked at this pdf file page 1021: http://ict.siit.tu.ac.th/~stanislav/Elementary%20Linear%20Algebra%20with%20Applications.pdf My goal is to create a function that transforms square images using the cat map. – user3080956 Jul 10 '14 at 13:35
  • **See also**: http://stackoverflow.com/a/28907857/2778484 – chappjc Mar 07 '15 at 04:19

3 Answers3

3

When I want to know whether a certain number is in a matrix, I typically use the ismemberf File Exchange Submission.

This basically allows you to check for a value with a certain tolerance, which is required as floating point numbers can be tricky, and 0.9600 may actually be 0.960000000001.

%Standard functions
I = find(0.3 == [0:0.1:1]) % Returns an empty matrix
[tf, loc]=ismember(0.3, 0:0.1:1) % returns false 

%Function with a small default tolerance
[tf, loc]=ismemberf(0.3, 0:0.1:1) % returns true

Basically that is it, but I will add an example of how to get the location to address your comment. Suppose you have a matrix M and you want to find the value 7 inside this matrix:

% The matrix
M=magic(5)
%Using ismemberf
[tf, loc] = ismemberf(7, magic(5))

%Finding where the value is located:
[I, J] = sub2ind(size(M),loc)

Actually you could use find here as well. You don't need to worry about rounding issues because you are using the same value twice. Then the last line would look like so:

[I,J] = find(M(loc)==M)

Note that I would expect sub2ind to perform better as it is a simpler function.

Dennis Jaheruddin
  • 21,208
  • 8
  • 66
  • 122
  • I use Matlab 7.11.0 2010b which does not have ismemberf – user3080956 Jul 10 '14 at 13:38
  • @user3080956 Matlab does not have `ismemberf` by default. But it is offered on the matlab file exchange website that I linked to. Just download the .m file and put it in any directory on your path. http://www.mathworks.nl/matlabcentral/fileexchange/23294-ismemberf – Dennis Jaheruddin Jul 10 '14 at 14:17
  • I need to determine in which row that specific value is. – user3080956 Jul 10 '14 at 15:06
  • @user3080956 Have added an example of how that could be achieved. – Dennis Jaheruddin Jul 10 '14 at 16:05
  • Thank you for your comments. I have done it with integers. I did not divide matrices. Is there a better approach to perform the Cat map transformation? E.g., using repmat or imresize. I would include an image if I had a higher reputation. Could you take a look at this pdf file page 1021 ?http://ict.siit.tu.ac.th/~stanislav/Elementary%20Linear%20Algebra%20with%20Applications.pdf There is a figure showing how the Cat map is done. – user3080956 Jul 10 '14 at 17:54
  • @user3080956 That is different question. I would encourage you to research it a bit yourself, and if you can't figure it out you can ask a new question. Make sure that it is well formulated (including an example and a definition of 'better') – Dennis Jaheruddin Jul 11 '14 at 08:20
1

You should not do an equality test on a double precision floating point number, see http://matlab.wikia.com/wiki/FAQ#Why_is_0.3_-0.2-0.1.28or_similar.29_not_equal_to_zero.3F for more details.

am304
  • 13,758
  • 2
  • 22
  • 40
1

MATLAB R2015a added the function ismembertol that solves this problem. From the documentation:

LIA = ismembertol(A,B,tol) returns an array containing logical 1 (true) where the elements of A are within tolerance of the elements in B. Otherwise, the array contains logical 0 (false). Two values, u and v, are within tolerance if

abs(u-v) <= tol*max(abs([A(:);B(:)]))

That is, ismembertol scales the tol input based on the magnitude of the data.

Note that there is also a new uniquetol function that behaves similarly.

Community
  • 1
  • 1
chappjc
  • 30,359
  • 6
  • 75
  • 132