Values like a +0. I are really annoying. Answers from

How to reduce expressions with complex coefficients in the form of a+0.*I? Is there a way to globally set when to treat a very small number as zero?

give me some clue, but I find $Post = Chop[#, 10^-16] &; doesn't work, for example :

Print[MatrixForm[FourierDCT[FourierDCT[{0, 0, 1, 0, 0}, 2], 3]]]

gives (0. -5.55112*10^-17 1. 1.38778*10^-17 1.38778*10^-17 ), which means the small digits still exist.

  • $\begingroup$ What's wrong with Print[MatrixForm[FourierDCT[FourierDCT[{0, 0, 1, 0, 0}, 2], 3] // Chop]]? You can't use Chop outside the MatrixForm if that's the problem you've been having. $\endgroup$ – Jonathan Shock May 7 '13 at 5:55
  • 2
    $\begingroup$ But you know, it's probably a mistake to try to always hide small numbers --- someday you may need to know that they are not really zero. Just choose Chop whenever you want to display things. $\endgroup$ – bill s May 7 '13 at 5:57
  • $\begingroup$ Jonathan Shock: I don't know Chop fails outside the MatrixForm. But doesn't $Post = Chop[#, 10^-16] &; tells Mathematica to neglect digits smaller than 10^-16 automatically? $\endgroup$ – novice May 7 '13 at 6:12
  • 1
    $\begingroup$ The default for all numbers is Complex. But if you use only rationals (and don't do stuff like Sqrt[-rational] then everything will remain rational. But if you do operations that generate complex numbers (like Sqrt or roots of polynmials, there are lots!) then you need to deal with it explicitly. You can always apply Re to take only the real part or Chop to remove small imaginary values. $\endgroup$ – bill s May 7 '13 at 8:35
  • 1
    $\begingroup$ Keep in mind that an array that contains both pure reals and complexes can't be packed, so it'll take more memory and calculations will be slower. An array with all complexes (some of which have imaginary part 0.) can be packed without problems. $\endgroup$ – Szabolcs May 7 '13 at 20:37
$PrePrint = Chop

will work fine for suppressing small approximate numbers in the display of your results. However, it won't have an effect on the the output generated by Print:

expr = FourierDCT[FourierDCT[{0, 0, 1, 0, 0}, 2], 3]

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


{0., 0., 1., 2.64289*10^-17, 1.54951*10^-18}

That's because $PrePrint (and also $Post) are applied after the expression has evaluated, which means (counter-intuitively) that Print has already printed by the time that $PrePrint does anything. (MatrixForm has nothing to do with the problem.)

To get Print to go along with the program, you could inject a Chop into it using the Villegas-Gayley hack:

  Print[expr__] /; ! TrueQ[inside] := 
    Block[{inside = True}, Print @@ Chop@{expr}]

Now we have


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

Note that this kind of thing may lead you into trouble, since the display of expr now doesn't match its internal representation. For example, if you want to find the positions of the zero elements, by looking at the displayed form, you might think that Position[expr, 0] would do the trick. But really you would need Position[expr, _?(Chop[#] == 0 &)] (or Position[Chop@expr, 0]).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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