Question

I want to truncate absolute values below an epsilon to 0, e.g.,

Truncate[{-3, -2, -1, 0, 1, 2, 3}, 1.5] -> {-3, -2, 0, 0, 0, 2, 3}

I guess I could write a function using Scan[] and If[], but is there a more idiomatic "one-liner" way of doing it in Mathematica?

Was it helpful?

Solution

The built in function Chop is almost exactly what you're looking for (it does work on lists, as in your example). One potential surprise is that it doesn't chop (truncate) integers, only floating point numbers. So for your example to work as you might expect, first convert your list to floating point with the N function:

Chop[N@{-3, -2, -1, 0, 1, 2, 3}, 1.5] -> {-3., -2., 0, 0, 0, 2., 3.}

As Ramashalanka shows, to do this sort of thing more generally, I recommend:

If[Abs[#]<1.5&, 0, #]& /@ {-3, -2, -1, 0, 1, 2, 3}

Ie, a lambda function mapped over the list.

OTHER TIPS

Lots of options that all work:

Map[If[Abs[#] < 1.5, 0, #] &, {-3, -2, -1, 0, 1, 2, 3}]

or the equivalent:

If[Abs[#] < 1.5, 0, #] & /@ {-3, -2, -1, 0, 1, 2, 3}

or, if you prefer:

ReplaceAll[{-3, -2, -1, 0, 1, 2, 3}, (x_ /; Abs[x] < 1.5) -> 0]

which is equivalent to:

{-3, -2, -1, 0, 1, 2, 3} /. (x_ /; Abs[x] < 1.5) -> 0

or

ReplaceAll[{-3, -2, -1, 0, 1, 2, 3}, (x_?(Abs[#] < 1.5 &)) -> 0]

which is equivalent to:

{-3, -2, -1, 0, 1, 2, 3} /. (x_?(Abs[#] < 1.5 &)) -> 0

Here is a method (f3) that is nearly an order of magnitude faster.

It is adapted from code by Fred Simons.


f1 = If[Abs[#] < 1.5, 0, #] & /@ # &;

f2 = # /. (x_ /; Abs[x] < 1.5) -> 0 &;

f3 = # (1 - Unitize@Clip[#, {-1.5, 1.5}, {0, 0}]) &;

lst = RandomInteger[{-100, 100}, 5000];

SameQ @@ (#@lst & /@ {f1, f2, f3})

First@Timing@Do[#@lst, {500}] & /@ {f1, f2, f3}

(* Out=  True                  *)

(* Out=  {0.406, 2.282, 0.047} *)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top