From: carlierm on
Hi

I have a signal in the time domain, and I need to perform some changes in
the spectrum of magnitude of such signal, and then I want to reconstruct
the signal and take it to the time domain again. The problem I have is that
i cannot get the signal in the time domain after the modifications. When I
take ifft, I get a vector of complex numbers, and I expect a vector or real
numbers. The code I have is as follows:

Fs=1024;
t=0:1/Fs:1;
x=sin(2*pi*t*200);
y=fft(x);
mx=abs(y);
ma=angle(y);
[C,I]=max(mx);
mx(I)=100;
for i=1:length(y)
y4(i)=mx(i)*cos(ma(i))+ j*mx(i)*sin(ma(i));
end
y6=ifft(y4);

I will appreciate any help.

Monica



From: Tim Wescott on
On Sun, 03 Jan 2010 08:29:00 -0600, carlierm wrote:

> Hi
>
> I have a signal in the time domain, and I need to perform some changes
> in the spectrum of magnitude of such signal, and then I want to
> reconstruct the signal and take it to the time domain again. The problem
> I have is that i cannot get the signal in the time domain after the
> modifications. When I take ifft, I get a vector of complex numbers, and
> I expect a vector or real numbers. The code I have is as follows:
>
> Fs=1024;
> t=0:1/Fs:1;
> x=sin(2*pi*t*200);
> y=fft(x);
> mx=abs(y);
> ma=angle(y);
> [C,I]=max(mx);
> mx(I)=100;
> for i=1:length(y)
> y4(i)=mx(i)*cos(ma(i))+ j*mx(i)*sin(ma(i));
> end
> y6=ifft(y4);
>
> I will appreciate any help.
>
> Monica

You don't say what tool you're doing this in; I assume it's Matlab, but
it could as easily be Octave, Scilab, or something else yet. Letting us
know would help.

Assuming that it's one of the three that I mentioned, here's several
things to check:

First, check the magnitude of the complex part of your answer. Scilab,
at least, nearly always decides that the return from an ifft is complex,
but the complex part is often scraping the limit of computational
accuracy. When you've got a real part with a maximum magnitude of 100,
and an imaginary part with a maximum magnitude of 10^-15, you can often
safely assume that you've got a vector of reals, with some round-off
error that happens to be complex.

Then, just to make sure that the world has not gone insane, see what you
get when you take ifft(fft(x)).

I _think_ that what you're doing by separating phase and magnitude is OK,
but you should probably also try commenting out the mx(I) = ... line, and
see what result you get.

I can't think of anything else. Good luck, let us know what you find.

--
www.wescottdesign.com
From: dbd on
On Jan 3, 6:29 am, "carlierm" <carliermon...(a)gmail.com> wrote:
> Hi
> ... When I
> take ifft, I get a vector of complex numbers, and I expect a vector or real
> numbers. The code I have is as follows:
> ...
>
> I will appreciate any help.
>
> Monica

Real non-DC frequency components in your input sequence are converted
by the fft into pairs of complex components symmetric about DC.
However you modify the magnitude of one of the components you must
also modify the magnitude of other to get the output of the ifft to be
approximately real. Then you still need to follow Tom's suggestion
about round-off errors in the imaginary component of the ifft output.

Dale B. Dalrymple
From: Fred Marshall on
Tim Wescott wrote:
> On Sun, 03 Jan 2010 08:29:00 -0600, carlierm wrote:
>
>> Hi
>>
>> I have a signal in the time domain, and I need to perform some changes
>> in the spectrum of magnitude of such signal, and then I want to
>> reconstruct the signal and take it to the time domain again. The problem
>> I have is that i cannot get the signal in the time domain after the
>> modifications. When I take ifft, I get a vector of complex numbers, and
>> I expect a vector or real numbers. The code I have is as follows:
>>
>> Fs=1024;
>> t=0:1/Fs:1;
>> x=sin(2*pi*t*200);
>> y=fft(x);
>> mx=abs(y);
>> ma=angle(y);
>> [C,I]=max(mx);
>> mx(I)=100;
>> for i=1:length(y)
>> y4(i)=mx(i)*cos(ma(i))+ j*mx(i)*sin(ma(i));
>> end
>> y6=ifft(y4);
>>
>> I will appreciate any help.
>>
>> Monica
>

Consider this:

If you fft a real time sequence then the real part is even and the
imaginary part is odd.

When you fft any sequence then the resulting sequence starts with an
index of zero and ends with an index of N-1 - relative frequency - if
the original sequence is a time sequence. And, you may assume that the
value at N would be the same as the value at zero - as you may consider
that it starts to repeat at that point. You may visualize this if you
put the data on a circular axis (i.e. the axis is a circle) instead of a
linear one.

Because the real part is even, it mirrors around Fs/2 or around N/2. If
the number of samples is even then there is a sample at that point and
it is the N/2+1th sample and it must be purely real because the
imaginary part is odd thus zero at that point. If the number of samples
is odd then there is no sample at Fs/2.
Because of the mirroring, the real part of the samples show up in equal
pairs around zero and the imaginary parts of the samples show up in
equal (but opposite sign) around zero.

The magnitude is always even. Because of this, the magnitude is
symmetrical about zero AND about Fs/2.

I note that you changed the magnitude at a single sample point.
Because of the above, what about the magnitude at the mirror image
point? By changing a single sample you have perforce changed the
evenness of the magnitude and I should say the real part. The resulting
ifft can therefore *not* be real.

Without solving the entire problem for you, I suggest you first make the
change at both I and at length(y)-I ... check my math here to keep the
magnitude an even function. Whether this guarantees that the real part
remains even and the imaginary part remains odd I leave as an important
exercise.

Also, how can you be sure that the conversion from magnitude and phase
back to real and imaginary is working OK. Have you considered phase
wrap first? i.e. what happens when the phase goes beyond 2pi?

P.S. Changing a single pair of mirrored samples (real and imaginary
now...) in frequency (which is equivalent to multiplying by a pair of
samples of selected value) is the same as convolving in time by a
sinusoid. Is that what you're trying to do?

Fred
From: Tim Wescott on
On Sun, 03 Jan 2010 11:12:15 -0800, Fred Marshall wrote:

> Tim Wescott wrote:
>> On Sun, 03 Jan 2010 08:29:00 -0600, carlierm wrote:
>>
>>> Hi
>>>
>>> I have a signal in the time domain, and I need to perform some changes
>>> in the spectrum of magnitude of such signal, and then I want to
>>> reconstruct the signal and take it to the time domain again. The
>>> problem I have is that i cannot get the signal in the time domain
>>> after the modifications. When I take ifft, I get a vector of complex
>>> numbers, and I expect a vector or real numbers. The code I have is as
>>> follows:
>>>
>>> Fs=1024;
>>> t=0:1/Fs:1;
>>> x=sin(2*pi*t*200);
>>> y=fft(x);
>>> mx=abs(y);
>>> ma=angle(y);
>>> [C,I]=max(mx);
>>> mx(I)=100;
>>> for i=1:length(y)
>>> y4(i)=mx(i)*cos(ma(i))+ j*mx(i)*sin(ma(i));
>>> end
>>> y6=ifft(y4);
>>>
>>> I will appreciate any help.
>>>
>>> Monica
>>
>>
> Consider this:
>
> If you fft a real time sequence then the real part is even and the
> imaginary part is odd.
>
-- snip --

> I note that you changed the magnitude at a single sample point. Because
> of the above, what about the magnitude at the mirror image point? By
> changing a single sample you have perforce changed the evenness of the
> magnitude and I should say the real part. The resulting ifft can
> therefore *not* be real.
>
-- snip --

Ah ha. I missed that, shouldn't have.

--
www.wescottdesign.com