Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Please consider the following:

zeros={0.,0};   
data={1, 0., 0}; 
DeleteCases[data, #]&/@zeros
Head/@zeros
(*{Real, Integer}*)
(*{{1, 0}, {1, 0.}}*)

For my understanding all integers (e.g. 0, 2) are element of the real numbers (e.g. 0.00000, 2.00000). So why would Mathematica not delete all zeros form data.

I know from here that one can solve the DeleteCases-problem via DeleteCases[Rationalize@data,0] but this is not the point here.

EDIT

The following test may explain my problem slightly better:

sets={Integers,Reals,Complexes};
test=Table[Element[j, i], {i, sets}, {j, zeros}];
(*{{False, True}, {True, True}, {True, True}}*)

test returns as expected that 0 is element of Integers, Reals and Complexes for which reason I would expect for DeleteCases[data, #]&/@zeros the following result:

{{1}, {1, 0.}}

For the latter 0. can not be deleted from data because I called delete all 0-Integers whereas in the first case all zeros can be deleted as I called delete all 0-Reals.

Note: Instead of 0 and 0. we could use also 2 and 2.. The value does not matter.

share|improve this question
    
Are you trying to do DeleteCases[data, 0 | 0.]? As far as I can tell your example works as expected. With /@ you are only deleting one type of zero at a time. –  Mr.Wizard Oct 22 '12 at 18:28
1  
I shall reopen this question, but I encourage you to expand and clarify it because as it presently reads it looks like a duplicate. –  Mr.Wizard Oct 22 '12 at 20:20
1  
Incidentally, try: Table[Element[j, i], {i, sets}, {j, zeros}] –  Mr.Wizard Oct 22 '12 at 20:22
1  
I agree with Mr.Wizard that this is a duplicate. Please explain why exactly it is not and how the other answers do not answer your question. As for 0==0., you should read up the documentation for Equal and SameQ... it's fully covered between the two. –  rm -rf Oct 22 '12 at 20:41
2  
Element is a mathematical operation, which is why it (correctly) says that 0 is an element of Integers/Reals/Complexes. However, 0. is a floating point representation of zero and is not an exact integer, hence False. It certainly is an element of Reals, and by extension, an element of Complexes which is a superset of Reals, which is why it returns True. DeleteCases uses pattern matching and relies on the heads (or the FullForm) and does not do a mathematical comparison. This is something you need to get comfortable with in order to use Mathematica effectively. –  rm -rf Oct 22 '12 at 21:41
show 3 more comments

2 Answers 2

up vote 4 down vote accepted

Element (of) is a mathematical operation, which is why it (correctly) says that 0 is an element of Integers, Reals and Complexes. However, $0.$ is a floating point representation of zero and is not an exact integer, hence it returns False for Element[0., Integer]. On the other hand, 0. certainly is an element of Reals, and by extension, an element of Complexes which is a superset of Reals, which is why it returns True for both these cases.

DeleteCases uses pattern matching and relies on the heads (or the FullForm) and does not do a mathematical comparison, which is why DeleteCases[list, 0] will not remove instances of 0. in list. The solution in this case is to either use 0 | 0. as the pattern, or use PossibleZeroQ to test the elements of list:

DeleteCases[data, _?PossibleZeroQ]
(* {1} *)

The difference between mathematical operations and the pattern matching logic is something you need to get comfortable with in order to use Mathematica effectively. Another example of a common mistake is to use pattern matching to perform algebraic manipulations.

share|improve this answer
    
...or, one might consider preprocessing the data: DeleteCases[Chop[list], 0] –  J. M. Oct 22 '12 at 22:57
    
@J.M. well, $10^{-11}$ is still not $0$, and going the extra length of using the second argument seems long winded :) –  rm -rf Oct 23 '12 at 0:14
add comment

DeleteCases uses the pattern matcher which matches against the FullForm of expressions. Just use Alternative:

In[]:= DeleteCases[{1, 0., 0}, 0. | 0]
Out[]= {1}

or a conditional pattern

In[]:= DeleteCases[{1, 0., 0}, _?(# == 0 &)]
Out[]= {1}

or

In[]:= DeleteCases[{1, 0., 0}, x_ /; x==0]
Out[]= {1}

This happens a lot with infinity be careful of the heads: Infinity // FullForm is DirectedInfinity[1]

share|improve this answer
1  
A bit more on the Infinity part: using Infinity in replacement rules or patterns works just as expected, because both expand out to DirectedInfinity (for example: DirectedInfinity[1] /. Infinity -> 1 and Infinity /. Infinity -> 1). The confusion, however, often occurs when one expects division by zero to occur, but then wants to disregard it and replace it with something arbitrary. In that case, it is not DirectedInfinity that's used, but ComplexInfinity and doing foo /. Infinity -> bar will not work –  rm -rf Oct 22 '12 at 20:39
    
@rm: to catch all forms of *Infinity, one should then match against the pattern _DirectedInfinity, since ComplexInfinity is the same as DirectedInfinity[]. –  J. M. Oct 23 '12 at 0:23
    
@J.M. Yes, that is correct. –  rm -rf Oct 23 '12 at 0:36
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.