# How to Chop correctly?

I want to count degeneracies in a list called spectrum. The list contains numbers of double (~ 15digits) precision. So it makes no sense if the noise below this precision is taken into account since it falsifies the result of degeneracy counting using Tally[]. So I applied SetPrecision.

degList = Tally[{#1, SetPrecision[#2, 15]} & @@@ spectrum];


But I still get e.g. {-0.047063080371693544, 4} {-0.047063080371693294, 4} (last number is the degeneracy level) which should be seen as equal numbers but are counted by Tally[] as different ones. What am I doing wrong?

• How about something like omegaij=Chop[Differences[spectrum], tol] and then tallying that? – acl Dec 21 '12 at 13:00
• Thank you for your comment. But what is wrong with my attempt? – pawel_winzig Dec 21 '12 at 13:22
• I'll add an answer to this comment in my answer because it's a bit long for here – acl Dec 21 '12 at 13:36

Use the second argument of Tally, thus:

Tally[{.00123, .00154}, Abs[#1 - #2] < .01 &]
(*{{0.00123, 2}}*)


Alternatively, look at energy level differences, omegaij=Chop[Differences[spectrum], tol], then Tally[omegaij].

Reply to comment (on what's wrong with the attempt in the question):

First, SetPrecision doesn't chop off digits; it instead sets the precision, see here).

Second, I am not sure what you intended {#1, SetPrecision[#2, 15]} & @@@ spectrum to do, but g@@@l just replaces the heads of everything at level 1 of l by g, for example,

g @@@ {a, b[c[d]], {{c}}}
{g, g[c[d]], g[{c}]}


If you try g[#1, #2] & @@@ {a, b, c} then nothing happens because the objects at level 1 are atomic (ie for the same reason that g @@ 3 evaluates to 3). If instead you try it on something with non-atomic objects at level 1, then it bombs:

g[#1, #2] & @@@ {a, b, c} Maybe you're looking for Map,

g /@ {1, 2, 3}
(*{g, g, g}*)


But I am probably missing something; what did you intend this to do?