3
$\begingroup$

I'm a big fan of Chop. It's fast and useful in pre-rounding transforms and things

Unfortunately it also necessarily unpacks a real PackedArray (it's rounding approximate 0 to true integer 0). It does that even when it doesn't actually have to:

bigList =
  BlockRandom[SeedRandom[1]; RandomReal[{}, {1000, 1000}]];

Developer`PackedArrayQ@bigList

True

Chop[bigList] === bigList

True

Chop[bigList] // Developer`PackedArrayQ

False

And, of course, it unpacks when it has to:

Chop[bigList, 10^-5] == bigList

False

Chop[bigList, 10^-5] // Developer`PackedArrayQ

False

Is there any built-in packed Chop?

I could of course implement an array chop like:

packChop =
 Compile[
  {
   {arr, _Real, 2},
   {tol, _Real}
   },
  Map[
   If[Abs[#] < tol, 0., #] &,
   arr,
   {2}
   ],
  RuntimeOptions -> "Speed"
  ]

packChop[bigList, 10^-$MachinePrecision] // Developer`PackedArrayQ

True

packChop[bigList, 10^-$MachinePrecision] // RepeatedTiming // First

0.071

Or just do it in top-level code:

chop[a_, t_] :=
 With[{r = N@t},
  Map[
   If[Abs[#] < r, 0., #] &,
   bigList,
   {2}
   ]
  ]

chop[bigList, 10^-$MachinePrecision] // Developer`PackedArrayQ

True

chop[bigList, 10^-$MachinePrecision] // RepeatedTiming // First

0.085

But it's always nice to use the built-ins (even if unpacking makes them slow):

uBigList = bigList;
uBigList[[1, 1]] = 1;

Chop@bigList // RepeatedTiming // First

0.089

Chop@uBigList // RepeatedTiming // First

0.033
$\endgroup$
2
  • 4
    $\begingroup$ I guess you are looking for Threshold... $\endgroup$ Jul 6, 2018 at 21:59
  • $\begingroup$ @HenrikSchumacher that is exactly what I’m looking for. Let’s see if there’s a duplicate we can resolve this to (feels like there should be although I didn’t see it earlier). $\endgroup$
    – b3m2a1
    Jul 6, 2018 at 22:40

0

Your Answer

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

Browse other questions tagged or ask your own question.