0
votes

I have a complex array in Matlab

x = [2+1i, 0.1+3i, 0.001+4i, 5+0.0002i, 6+0.0013i]

and I want to make the real or imaginary parts equal to zero if they are smaller than some tolerance.

For example, if the real tolerance is 0.01 and imaginary tolerance is 0.001, then after the operation my array should look like this:

x = [2+1i, 0.1+3i, 0+4i, 5+0i, 6+0.0013i]

Of course I can split x into its real and imaginary parts, round them independently and then join them back. However, the actual arrays are quite big (100k*100k) each I don't want to waste memory doing this.

Is there a way to round the individual parts of a complex array without splitting it in two?

1
Easy way is to round all numbers to some precision: (you can use round or floor or fix in the same way), " y=round(x./accuracy).*accuracy " - Mendi Barel
@MendiBarel That doesn't really address this question at all, which is about rounding real and imaginary parts separately... - Wolfie

1 Answers

2
votes

First, let's define your tolerances

tolReal = 0.01;
tolImag = 0.001;

You could create a function

f = @(z) real(z).*(real(z)>tolReal) + 1i.*imag(z).*(imag(z)>tolImag);

We can test this works on your example array:

>> x=[2+1i 0.1+3i 0+4i 5+0i 6+0.0013i]
>> y = f(x)
y = 
   2 + 1i   0.1 + 3i   0 + 4i   5 + 0i   6 + 0.0013i  

The advantage of using this functional form is that we can use arrayfun and avoid creating 100k*100k logical matrices

y = arrayfun( f, x );

This will produce the same result, but with a lower memory footprint. This may be quicker than a logical/vectorized approach for large matrices (like in your case) because we're avoiding the creation of large matrices. For small matrices you may find it's slower as it's basically a loop in disguise.