# Replace very small numbers by zero in the output of a list

I have a long nested list, but many elements are numbers of order 10^-18 or less, e.g.

{{0.217548, -0.217548, -0.0373272, -9.83823*10^-18, -8.13807*10^-19}, \
{0.217548, 0.217548, 0.0373272, 7.54332*10^-18, 6.23849*10^-19}, \
{0.183095, 0.0504041, 0.00207916, -0.214279, -0.0218996}, \
{0.985472, -0.193791, -0.461242, 4.17611*10^-20, 1.22184*10^-20}, \
{0.985472, 0.193791, 0.461242, -1.18329*10^-30, -9.86076*10^-31},
{0.60405, 9.7862*10^-23, -9.11593*10^-24, -1.54354*10^-22, -1.91278*10^-23}, \
{0.80994, 0.556147, 0.623645, 0.558531, 0.625958}}


Then, to make the output more readable, I want to print in the output the numbers with absolute value smaller than 10^-18 as zeros.

What is the smartest and fastest way to do this?

-
How about N[results, precision] (reference.wolfram.com/mathematica/ref/N.html)? – Tony Dong Mar 19 '13 at 15:59
If dealing with reals, Chop your list. The second argument defines the threshold for zero. – Yves Klett Mar 19 '13 at 16:07
@YvesKlett Exactly what I needed. Thanks. – psmith Mar 19 '13 at 16:12
Why don´t you provide a sample list in your question? That would be instructive. BTW, not sure if this is not a duplicate or too localized (we´ll see). – Yves Klett Mar 19 '13 at 16:15
Perhaps you should also change the question title a bit, since you are not really after the precision but a simple chopping (at least my answer assumes that). – Yves Klett Mar 19 '13 at 16:40

This is rather basic ,but since it helped you, I´ll post the answer and leave it to the other users to judge.

The second argument to Chop (see Details section) defines the magnitude below which values will be replaced by 0.

l = {{0.217548, -0.217548, -0.0373272, -9.83823*10^-18, \
-8.13807*10^-19}, {0.217548, 0.217548, 0.0373272, 7.54332*10^-18,
6.23849*10^-19}, {0.183095, 0.0504041,
0.00207916, -0.214279, -0.0218996}, {0.985472, -0.193791, \
-0.461242, 4.17611*10^-20, 1.22184*10^-20}, {0.985472, 0.193791,
0.461242, -1.18329*10^-30, -9.86076*10^-31}, {0.60405,
9.7862*10^-23, -9.11593*10^-24, -1.54354*10^-22, \
-1.91278*10^-23}, {0.80994, 0.556147, 0.623645, 0.558531, 0.625958}};

Chop[l, 10^-18]


{{0.217548, -0.217548, -0.0373272, -9.83823*10^-18, 0},
{0.217548, 0.217548, 0.0373272, 7.54332*10^-18, 0},
{0.183095, 0.0504041, 0.00207916, -0.214279, -0.0218996},
{0.985472, -0.193791, -0.461242, 0, 0},
{0.985472, 0.193791, 0.461242, 0, 0},
{0.60405, 0, 0, 0, 0}, {0.80994, 0.556147, 0.623645, 0.558531, 0.625958}}

-

You can also use Threshold:

l = {{0.217548, -0.217548, -0.0373272, -9.83823*10^-18, -8.13807*10^-19},
{0.217548, 0.217548, 0.0373272, 7.54332*10^-18,  6.23849*10^-19},
{0.183095, 0.0504041,  0.00207916, -0.214279, -0.0218996},
{0.985472, -0.193791, -0.461242, 4.17611*10^-20, 1.22184*10^-20},
{0.985472, 0.193791,  0.461242, -1.18329*10^-30, -9.86076*10^-31},
{0.60405,  9.7862*10^-23, -9.11593*10^-24, -1.54354*10^-22, -1.91278*10^-23},
{0.80994, 0.556147, 0.623645, 0.558531, 0.625958}};

Threshold[l, 10^-18] (* or Threshold[l,{"Hard",10^18}] *)

(* {{0.217548, -0.217548, -0.0373272, -9.83823*10^-18, 0.},
{0.217548,  0.217548, 0.0373272, 7.54332*10^-18, 0.},
{0.183095, 0.0504041, 0.00207916, -0.214279, -0.0218996},
{0.985472, -0.193791, -0.461242,  0., 0.},
{0.985472, 0.193791, 0.461242, 0., 0.},
{0.60405, 0., 0.,  0., 0.},
{0.80994, 0.556147, 0.623645, 0.558531, 0.625958}} *)


FWIW, it seems to be faster than Chop for large lists:

 dt = RandomReal[1, {1000000}, WorkingPrecision -> 40];
dtchp = Chop[dt, 10^-18]; // AbsoluteTiming
(* {0.3110311,Null}*)
dtthrshld = Threshold[dt, 10^-18]; // AbsoluteTiming
(* {0.240023,Null} *)
dtchp == dtthrshld
(* True *)

-
My machine puts Chop slight in front of Threshold with altered precision (and using real 10.^-18 helps as well), while Threshold smokes Chop for standard precision - any explanations? – Yves Klett Mar 19 '13 at 17:45
@Yves, good observation (confirmed on Version 9 Windows Vista 64bit). Don't have any idea why, though. – kglr Mar 19 '13 at 18:19
@YvesKlett probable explanation is that Chop replaces the values with exact zero, which involves unpacking the list if packed to start with. Threshold uses a machine zero and doesn't need to unpack. Since arbitrary precision values can't be stored in packed arrays anyway, Chop and Threshold are going to be similar in this case. – Oleksandr R. Jan 1 '14 at 22:51

The solutions above would be also my choice, but to give a more complete picture, here is an additional approach.

This generates the list with small valuse and those about a unity:

lst = Table[RandomReal[{-2, 2}]*10^RandomReal[{-10, 1}], {45}]


this solves the task replacing items smaller than 10^-5:

lst /. x_ /; Abs[x] <= 10^-5 -> 0


This is the result:

 {-0.00716429, -0.0364071, -0.000281284, 0, -0.000856377, 0, 0.164907, \
-0.0516522, -0.000840723, 0, 0.0467477, -12.1348, -0.636598, \
-0.0000171288, 0, 0, 0, 0.0910157, -0.0000228134, 0, 0, -0.396028, 0, \
0, 0, 0, -0.129861, -0.000599652, 0, 0, -0.00824202, 0, 0, 0.0181993, \
-0.0000162593, 0.00320663, -0.248421, 0, 0, 0, 0.0031162, 0.0363161, \
0.0216937, 0, 0}

-
May I ask a question? Is there any alternative to display two decimal places without AccountForm? I follow your advice and append "AccountForm" in front of the expression AccountingForm[lst /. x_ /; Abs[x] <= 10^-4 -> 0, 2] e.g {0.342416, 0.304959, 0, 0.352625} -> {0.34, 0.3, 0, 0.35} – Nelson Mok Feb 18 at 7:03
@Nelson Mok I am not quite sure to have understood your aim. I have the impression that just for visualization you would like to have a shorted representation of the terms in the list, say, with two figures after comma, right? If yes, you may use the NumberForm function in such a way: lst = Table[RandomReal[{-2, 2}]*10^RandomReal[{-10, 1}], {45}]; lst1 = lst /. x_ /; Abs[x] <= 10^-5 -> 0; Map[NumberForm[#, {3, 2}] &, lst1] . Have fun! – Alexei Boulbitch Feb 18 at 8:33
thank you, your suggest resolved the problem. – Nelson Mok Feb 18 at 9:10