13
$\begingroup$

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?

$\endgroup$
5
  • $\begingroup$ How about N[results, precision] (reference.wolfram.com/mathematica/ref/N.html)? $\endgroup$
    – Tony Dong
    Commented Mar 19, 2013 at 15:59
  • 2
    $\begingroup$ If dealing with reals, Chop your list. The second argument defines the threshold for zero. $\endgroup$
    – Yves Klett
    Commented Mar 19, 2013 at 16:07
  • $\begingroup$ @YvesKlett Exactly what I needed. Thanks. $\endgroup$
    – psmith
    Commented Mar 19, 2013 at 16:12
  • $\begingroup$ 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). $\endgroup$
    – Yves Klett
    Commented Mar 19, 2013 at 16:15
  • $\begingroup$ 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). $\endgroup$
    – Yves Klett
    Commented Mar 19, 2013 at 16:40

3 Answers 3

14
$\begingroup$

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}}

$\endgroup$
9
$\begingroup$

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 *)
$\endgroup$
3
  • $\begingroup$ 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? $\endgroup$
    – Yves Klett
    Commented Mar 19, 2013 at 17:45
  • $\begingroup$ @Yves, good observation (confirmed on Version 9 Windows Vista 64bit). Don't have any idea why, though. $\endgroup$
    – kglr
    Commented Mar 19, 2013 at 18:19
  • 4
    $\begingroup$ @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. $\endgroup$ Commented Jan 1, 2014 at 22:51
4
$\begingroup$

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}
$\endgroup$
3
  • $\begingroup$ 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} $\endgroup$ Commented Feb 18, 2016 at 7:03
  • 1
    $\begingroup$ @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! $\endgroup$ Commented Feb 18, 2016 at 8:33
  • $\begingroup$ thank you, your suggest resolved the problem. $\endgroup$ Commented Feb 18, 2016 at 9:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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