# PackedArray version of Chop

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

DeveloperPackedArrayQ@bigList

True

Chop[bigList] === bigList

True

Chop[bigList] // DeveloperPackedArrayQ

False


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

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

False

Chop[bigList, 10^-5] // DeveloperPackedArrayQ

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] // DeveloperPackedArrayQ 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] // DeveloperPackedArrayQ 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

• I guess you are looking for Threshold`... Commented Jul 6, 2018 at 21:59
• @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). Commented Jul 6, 2018 at 22:40