# Removing numerical artifacts from a table of values

For some function, f[x, y], I have generated a table of values

Table[f[x, y], {x, {1, 2, 3}}, {y, {1, 2, 3}}]


which generates

{{f[1, 1], f[1, 2], f[1, 3]},
{f[2, 1], f[2, 2], f[2, 3]},
{f[3, 1], f[3, 2], f[3, 3]}}.


However, many of these values are negative or complex; however, these are numerical artifacts, and I want to set them to 0, unless they are positive real.

If I have a large table of this kind, is there a way to set values that are negative or complex to 0?

Here is one approach:

t = {{-3, 5, 2 + 7 I}, {1/2, -0.7, 1.3 - I}};

t*Boole@Positive@t // Chop

{{0, 5, 0}, {1/2, 0, 0}}


ReplaceAll (/.) is a very handy way of easily replacing elements of a list:

t = {{-3, 5, 2 + 7 I}, {1/2, -0.7, 1.3 - I}};
t /. {x_ /; ! Positive[x] -> 0}

(* {{0, 5, 0}, {1/2, 0, 0}} *)


If you ever want to just get rid of all the complex or negative elements (instead of setting them to zero) you can do

t /. {x_ /; ! Positive[x] -> Nothing}
Cases[t, x_ /; Positive[x], 2]

(* {{5}, {1/2}}
{5, 1/2}     *)


(there are also many, many other ways of doing that).

If the artifacts are sufficiently small, you can use just Chop.

To demonstrate this, I first need data that exhibits the right characteristics.

positive[] := RandomReal[{1., 5.}]
negative[] := -RandomReal[{1., 5.} 10^-11]
complex[] := positive[] + I RandomChoice[{-1, 1}] negative[]

SeedRandom;
data = Through[RandomChoice[{positive, negative, complex}, 12][]]

{4.98146 + 2.89887*10^-11 I,
2.54797 + 2.45814*10^-11 I,
3.62342,
2.97821 + 1.91297*10^-11 I,
-2.31221*10^-11,
4.50281,
2.01652 - 1.78838*10^-11 I,
-2.30211*10^-11,
-4.07092*10^-11,
2.6675*10^-11,
4.15392,
-1.68444*10^-11}


With this data

Chop[data]


gives

{4.98146, 2.54797, 3.62342, 2.97821, 0, 4.50281, 2.01652, 0, 0, 0, 4.15392, 0}


Note that Chop takes a 2nd argument that allow you to adjust the granularity at which it operates.

To also eliminate values like Indeterminate, -Infinity etc.

vals = {7, Indeterminate, 1 + I, I, -1, 0, 10.^-24};

Replace[vals,
x_ /; Negative[x] || ! NumericQ[x] || Head[x] == Complex || x < 10^-6 :> 0, {1}]


{7, 0, 0, 0, 0, 0, 0}