1

Lets generate a large grid

grid=Table[{i,j},{i,0,10,.01},{j,0,10,.01}]
MemberQ[grid,{7.02,.02}]

The above MemberQ gives me False. (even though it must be true because the grid has every pair from (0,0) to (10,10) in increments of (.01)

It also gives me false for every ordered pair that starts with 7.02

I have tried wrapping the grid and the ordered pair in N function, but it did not solve the problem

I have also tried using a subset of the grid, i.e. grid[[703]]

replacing MemberQ with FreeQ does work though

(even stranger, I started a new kernel and tried the exercise again and now both MemberQ and FreeQ are giving me false for every ordered pair... i'll try restarting mathematica I guess.)

majmun
  • 207
  • 1
  • 6
  • 1
    I think you need to flatten your list: MemberQ[Flatten[grid, 1], {7.02, 0.02}]

    However, this doesn't solve the problem, and the result is still False. Surprisingly, MemberQ[Flatten[grid, 1], {7.03, 0.02}] gives True as output..

    – Fraccalo Jan 29 '20 at 11:45
  • Yes, they seem to be the same (or at least similar enough). Sorry about that. – majmun Jan 29 '20 at 12:27
  • @Kuba Now I did accidentally what you tried to prevent: Closing this post single-handedly. -.- Anyways, this is clearly a duplicate. – Henrik Schumacher Jan 29 '20 at 12:28
  • 1
    @HenrikSchumacher nothing wrong with that. Especially if that is your area. I wouldn't hesitate with a front end related question. And, majmun, no worries, it is not always easy to find an answer within existing ones. – Kuba Jan 29 '20 at 12:33

2 Answers2

4

Don't use pattern matching with floating point numbers. That is the problem. Look at this:

With[{pts = Flatten[grid, 1]},
 Min[Norm /@ (pts - ConstantArray[{7.02, .02}, Most@Dimensions[pts]])]
 ]

8.88178*10^-16

Better use a (relative) tolerance and a significantly faster method like Nearest:

pts = Developer`ToPackedArray@Flatten[N@grid, 1];
size = Sqrt[Max[Total[(pts^2), {2}]]];
nf = Nearest[pts -> "Index"];
containedQ[pt_] := Length[nf[pt, {1, size $MachineEpsilon}]] > 0;

containedQ[{7.02, .02}]

True

Henrik Schumacher
  • 106,770
  • 7
  • 179
  • 309
  • Couple questions about your code if you have a moment to answer: 1) nf is a nearest function (because you didn't specify a point)? 2) What is the {1, size $MachineEpsilon} in containedQ doing? 3)overall, this code is defining a tolerance for how close a point needs to be to be considered the same, and containedQ being true means there is such a point, correct? Sorry about commenting on a closed question/duplcate. – majmun Jan 29 '20 at 13:29
  • No problem, this is a site to ask questions. =) At 1) Yes! That's why I called it nf. The function is set up so that it returns only the indices of points found. This is a bit more efficient that returning the points themselves. – Henrik Schumacher Jan 29 '20 at 13:36
  • 1
    At 2) size $MachineEpsilon tells nf to look up points only in distance at most size $MachineEpsilon. 1 means that at most one point index should be returned. So the return of nf[pt, {1, size $MachineEpsilon}] is a list of at exactly one integer if there is a point in pts that is closer to pt than size $MachineEpsilon; otherwise, nf[pt, {1, size $MachineEpsilon}] returns the empty list {}. So we are left to check whether the Length of the output list is greater than 0. 3) Exactly! =D – Henrik Schumacher Jan 29 '20 at 13:36
  • Thats very helpful. Thank you! – majmun Jan 29 '20 at 13:39
  • You're welcome! – Henrik Schumacher Jan 29 '20 at 13:40
3

Too long for a comment, but not really an answer:

there is something weird going on with MemberQ:

grid = Flatten[Table[{i, j}, {i, 0, 7.1, .01}, {j, 0, 0.1, .01}], 1];
MemberQ[grid, {7.02, 0.02}]

grid = Flatten[Table[{i, j}, {i, 3, 7.1, .01}, {j, 0, 0.1, .01}], 1];
MemberQ[grid, {7.02, 0.02}]

grid = Flatten[Table[{i, j}, {i, 3.01, 7.1, .01}, {j, 0, 0.1, .01}], 1];
MemberQ[grid, {7.02, 0.02}]

grid = Flatten[Table[{i, j}, {i, 4, 7.1, .01}, {j, 0, 0.1, .01}], 1];
MemberQ[grid, {7.02, 0.02}]

grid = Flatten[Table[{i, j}, {i, 7, 7.1, .01}, {j, 0, 0.1, .01}], 1];
MemberQ[grid, {7.02, 0.02}]

False

False

True

True

True

It looks like for values of i starting from 0 up to 3 the code doesn't work, while from 3.01 to 7 it does work...

Rounding to the second decimal point works:

grid = Flatten[Table[{i, j}, {i, 0, 7.1, .01}, {j, 0, 0.1, .01}], 1];
MemberQ[Round[grid, 0.01], Round[{7.02, 0.02}, 0.01]]

True

I'm tempted to say that this is a bug, let's see what other people thinks..

Fraccalo
  • 6,057
  • 13
  • 28