From: carlierm on 3 Jan 2010 09:29 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 3 Jan 2010 12:40 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 3 Jan 2010 13:37 On Jan 3, 6:29 am, "carlierm" 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 3 Jan 2010 14:12 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 3 Jan 2010 20:53 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  |  Next  |  Last Pages: 1 2 Prev: PhD s from Convolution Integral ThreadNext: extended kalman filter going berserk