Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
ignore imaginary numbers only if they're small

Subject: ignore imaginary numbers only if they're small

From: Juliette Salexa

Date: 22 Apr, 2010 14:35:19

Message: 1 of 8

Hello,
My program gives me an output like this:

  1.000000000000000
  0.485400238849356
  0.046127510002059
  0.564148944841658
  0.311156957578463 + 0.000000000000000i
  0.199273442026241 + 0.000000000000000i
  0.199273442026241 + 2.155352552523552i

In the last value the imaginary part is necessary, but in the 2nd and 3rd last values, storing the real number as a complex number seems like a waste of memory and is suboptimal for practical reasons.

Is there a way where I could set matlab to store complex numbers as real numbers if the imaginary part is smaller than some threshold ?

I'd like to see if there's an easy method to do this globally rather than inserting IF statements into my program.

Cheers!

Subject: ignore imaginary numbers only if they're small

From: Sean

Date: 22 Apr, 2010 14:58:22

Message: 2 of 8

"Juliette Salexa" <juliette.physicist@gmail.com> wrote in message <hqpmr7$ipd$1@fred.mathworks.com>...
> Hello,
> My program gives me an output like this:
>
> 1.000000000000000
> 0.485400238849356
> 0.046127510002059
> 0.564148944841658
> 0.311156957578463 + 0.000000000000000i
> 0.199273442026241 + 0.000000000000000i
> 0.199273442026241 + 2.155352552523552i
>
> In the last value the imaginary part is necessary, but in the 2nd and 3rd last values, storing the real number as a complex number seems like a waste of memory and is suboptimal for practical reasons.
>
> Is there a way where I could set matlab to store complex numbers as real numbers if the imaginary part is smaller than some threshold ?
>
> I'd like to see if there's an easy method to do this globally rather than inserting IF statements into my program.

 a(imag(a)<2) = real(a(imag(a)<2))

Subject: ignore imaginary numbers only if they're small

From: Mark Shore

Date: 22 Apr, 2010 15:16:05

Message: 3 of 8

"Juliette Salexa" <juliette.physicist@gmail.com> wrote in message <hqpmr7$ipd$1@fred.mathworks.com>...
> Hello,
> My program gives me an output like this:
>
> 1.000000000000000
> 0.485400238849356
> 0.046127510002059
> 0.564148944841658
> 0.311156957578463 + 0.000000000000000i
> 0.199273442026241 + 0.000000000000000i
> 0.199273442026241 + 2.155352552523552i
>
> In the last value the imaginary part is necessary, but in the 2nd and 3rd last values, storing the real number as a complex number seems like a waste of memory and is suboptimal for practical reasons.
>
> Is there a way where I could set matlab to store complex numbers as real numbers if the imaginary part is smaller than some threshold ?
>
> I'd like to see if there's an easy method to do this globally rather than inserting IF statements into my program.
>
> Cheers!

See Sean's example and bear in mind if these values are returned in a mixed array then the reals are still stored in complex format (but with an imaginary component of 0 and isreal return of true).

Subject: ignore imaginary numbers only if they're small

From: James Tursa

Date: 22 Apr, 2010 15:32:05

Message: 4 of 8

"Juliette Salexa" <juliette.physicist@gmail.com> wrote in message <hqpmr7$ipd$1@fred.mathworks.com>...
> Hello,
> My program gives me an output like this:
>
> 1.000000000000000
> 0.485400238849356
> 0.046127510002059
> 0.564148944841658
> 0.311156957578463 + 0.000000000000000i
> 0.199273442026241 + 0.000000000000000i
> 0.199273442026241 + 2.155352552523552i
>
> In the last value the imaginary part is necessary, but in the 2nd and 3rd last values, storing the real number as a complex number seems like a waste of memory and is suboptimal for practical reasons.

In general, you will not be able to save any memory. Suppose you had a 1MB real array X. In that case MATLAB only stores the real part, there is no memory allocated for the imaginary part. Now suppose you change only *one* element in that 1MB array to have a non-zero imaginary part, e.g. X(1) = X(1) + 2i. All of a sudden MATLAB will have to create an additional 1MB imaginary part for X, even though the vast majority of this imaginary part is 0. There is no way around this given the way MATLAB stores data for the variables. Yes, it seems like a waste, but that is the way it is. But you have this penalty in other languages also (e.g., Fortran and C), so don't be too disappointed. In your above example the first four elements have blanks for the imaginary part when printing the output. Don't be fooled by this into thinking that there is no storage for this. In fact, there is storage
allocated for imaginary parts to *all* of the elements printed, even if some of them print blanks for the imaginary parts.

> Is there a way where I could set matlab to store complex numbers as real numbers if the imaginary part is smaller than some threshold ?

tol = 1e-10;
Y = abs(imag(X))<tol;
X(Y) = real(X(Y));

Be aware, however, that this simply sets the imaginary parts of the elements near zero to exactly zero. It will *not* save any memory. As long as you have at least one non-zero imaginary part in the array, the entire imaginary part of the array will be allocated.

James Tursa

Subject: ignore imaginary numbers only if they're small

From: Cris Luengo

Date: 22 Apr, 2010 16:05:05

Message: 5 of 8

"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <hqpq5l$pka$1@fred.mathworks.com>...
> tol = 1e-10;
> Y = abs(imag(X))<tol;
> X(Y) = real(X(Y));

You could also compare the magnitudes of the imaginary and real parts:

Y = abs(real(X)) > 1e6 * abs(imag(X));
X(Y) = real(X(Y));

Subject: ignore imaginary numbers only if they're small

From: Matt Fig

Date: 22 Apr, 2010 16:46:22

Message: 6 of 8

If you are really concerned about memory, you could consider using sparse storage for the imaginary part of the array (assuming the imaginary part is indeed sparse).


% Example data
M = complex(rand(6,1),rand(6,1)./(10.^ceil(rand(6,1)*14)))

% Storage scheme
R = real(M);
I = imag(M);
clear M % Otherwise what is the point?
I(I<tol) = 0; % tol as you wish
I = sparse(I);

Subject: ignore imaginary numbers only if they're small

From: James Tursa

Date: 22 Apr, 2010 16:58:21

Message: 7 of 8

"Matt Fig" <spamanon@yahoo.com> wrote in message <hqpugu$k1u$1@fred.mathworks.com>...
> If you are really concerned about memory, you could consider using sparse storage for the imaginary part of the array (assuming the imaginary part is indeed sparse).
>
>
> % Example data
> M = complex(rand(6,1),rand(6,1)./(10.^ceil(rand(6,1)*14)))
>
> % Storage scheme
> R = real(M);
> I = imag(M);
> clear M % Otherwise what is the point?
> I(I<tol) = 0; % tol as you wish
> I = sparse(I);

I had thought of this and almost included that in my post, but decided not to because of the limited usefulness of this setup IMO. If you wanted to work with it in any way that required the parts to be combined together as a complex array (e.g., maybe as an argument to a pre-existing function) then there goes your memory savings. And writing loops to work with the elements individually would likely be painfully slow. But, admittedly, the usefulness of the sparse approach depends on how OP intends to use the arrays downstream.

James Tursa

Subject: ignore imaginary numbers only if they're small

From: Matt Fig

Date: 22 Apr, 2010 17:25:15

Message: 8 of 8

"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message
> I had thought of this and almost included that in my post, but decided not to because of the limited usefulness of this setup IMO. If you wanted to work with it in any way that required the parts to be combined together as a complex array (e.g., maybe as an argument to a pre-existing function) then there goes your memory savings. And writing loops to work with the elements individually would likely be painfully slow. But, admittedly, the usefulness of the sparse approach depends on how OP intends to use the arrays downstream.
>
> James Tursa

True enough, James. It will be up to the OP to figure out what is really needed.
I should have added that in accessing the elements of the array with the above storage scheme, these are equivalent:

M(n) % After tolerance applied.
complex(R(n),I(n))

But as James points out, the usefulness of this scheme (or lack thereof) will depend on what is being done with the data.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us