Convert near zero complex parts to 0

In R2020a, I took a complex vector and converted near zero parts to zero. It took two long lines to do it. Can it be done in one line and not so long lines?
yy
yyFix = yy;
yyFix( abs( real(yyFix) ) < 1e-10 ) = 1j * imag(yyFix( abs( real(yyFix) ) < 1e-10 ) );
yyFix( abs( imag(yyFix) ) < 1e-10 ) = real(yyFix( abs( imag(yyFix) ) < 1e-10 ));
yyFix
The good output is:
yy =
1 + 0i
6.12323399573677e-17 + 1i
-1 + 1.22464679914735e-16i
-1.83697019872103e-16 - 1i
yyFix =
1 + 0i
0 + 1i
-1 + 0i
0 - 1i
I see that eps = 2.22044604925031e-16, but I would like to zero out the real and/or imag parts that are not as close to zero as eps.
<<EDIT 2021-04-01>> The +/-1 yy values can have arbitrary amplitudes. I assume that length(yy) > 1e8 for each signal section and/or input file.

 Accepted Answer

Does the following do what you want
yyFix = round(yy*10^n)/10^n;
where you choose n as desired.

6 Comments

format long g
yy = [
1 + 0i
6.12323399573677e-17 + 1i
-1 + 1.22464679914735e-16i
-1.83697019872103e-16 - 1i]
yy =
1 + 0i 6.12323399573677e-17 + 1i -1 + 1.22464679914735e-16i -1.83697019872103e-16 - 1i
round(yy,10)
ans =
1 + 0i 0 + 1i -1 + 0i 0 - 1i
I learned two things here. format long g is same as format longg, and that round "treats the real and imaginary parts independently". I should not have picked such clean values for the non-zero complex parts. If length(yy) > 1e8 in each section or file and yy has arbitrary amplitudes for the real and imag parts, then how to proceed? I <<EDIT>> the OP to reflect this. Assume the +/-1's can be any double value to be general.
The amplitudes only make a difference if you want to preserve full precision for values with abs() > 1e-10 . For example if you had 1.234e-9 and did not want that to be rounded as 12e-10 -> 1.2e-9, then there would be some changes needed.
If that is what you need, then splitting into real and imaginary is probably about the best you can do without using mex.
format long g
yy = [
1e8 + 0i
6.12323399573677e-17 + 1e11i
-1e-3 + 1.22464679914735e-16i
-1.83697019872103e-16 - 1e-5i]
yy =
100000000 + 0i 6.12323399573677e-17 + 100000000000i -0.001 + 1.22464679914735e-16i -1.83697019872103e-16 - 1e-05i
round(yy,10)
ans =
100000000 + 0i 0 + 100000000000i -0.001 + 0i 0 - 1e-05i
Thanks a lot. I think the round(yy,n) is the cleanest formulation. Was curious as to how MEX could improve the situation.
mex could, in some cases, work "in place", which would remove the need to create temporary variables for real and imaginary part, then temporary variables for the conditional results, and putting the results together.
Thanks. I will keep this Mex thought in mind and ask another question some time since I don't get how that would work. Another day. :)

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!