Why does my amplitude change upon inverse Fourier Transform when I am only randomizing the phase of the fourier transform using Python numpy?

I am trying to make a surrogate time series of a discrete data series using python, basically I wish to keep the amplitude same and change the frequency

I take a Fourier Transform of the data I separate the angles and the amplitudes of each fourier coefficient I keep the amplitudes intact while randomizing the phase angles I multiply the amplitudes with the new phases then take an inverse Fourier Transform However, when I plot the inverse transform, it does not match the values of the original data series Following is my python script:

import numpy as np
import matplotlib.pyplot as plt

x=np.linspace(1,12,12)
y=np.array([23,40,3,100,161,667,845,231,978,102,79,27])

#Get Fourier coefficients into amplitude and phases
ft=fft.rfft(y)
amp=np.abs(ft)
phi_old=np.angle(ft)
tlast=phi_old[-1]

#-Randomize phase keeping amplitude unchanged
phi_new=np.random.uniform(0,1.,size=phi_old.shape)+phi_old
phi_new[-1] = tlast # restore Nyquist bin original phase
nft=amp*np.cos(phi_new)+(1j*amp1*np.sin(phi_new))

#Take ifft
y2=fft.irfft(nft)

#Plot 'em
f=plt.figure(figsize=(7,7))
ax1.plot(x,y)
ax1.grid()
plt.title("x vs y")

ax2.grid()
ax2.plot(x,y2)
plt.title("Inverse Fourier Transform of y")

plt.tight_layout()
plt.show()


This script however seems to work well with y=sin(x) I have tried using fft and ifft instead of rfft and irfft but the values do not match with the original data. Again, I just wish to change the shift the plot, or change it's frequency, without altering the y-values, like if we change the phase of a sine wave it gets shifted, but its amplitude does not change, I am trying to achieve exactly that for my discrete data. What am I doing wrong? Please help.(see plot)

• Is your signal "y2" complex? If so, you might be plotting only the real part. Jun 19 '21 at 6:15
• Dear cjferes, y2 is a real ifft of a (complex) function, nft, which I am trying to use as a phase randomized function for the original fourier transform ft. I tried using fft and ifft in the places of rfft and irfft but still do not meet my expectations
– Modl
Jun 19 '21 at 6:27
• "Change frequency without altering y-values" "change phase without altering y-values" - neither is possible, to change these necessarily means to change the signal. It's unclear what you're trying to achieve. Do you mean to randomize phase without changing magnitude of FFT? Because you did. Jun 19 '21 at 6:58
• OverLordGoldDragon, yes, I wish to randomize the phase without changing the magnitude of the FFT. Very simply put, Is there any way I could stretch my original plot or shrink it along the x-axis (within x coordinates 1-12) keeping the y coordinate points same?
– Modl
Jun 19 '21 at 7:01
• You already achieved "change phase but not magnitude"; you're plotting the signals, not their spectrums. As for stretching the signal, that's not the same as randomizing phase; for one, output and input must differ in length (in general case). So are you trying to stretch, or randomize? (also use @ when replying, @Modl) Jun 19 '21 at 7:11

OP seeks to randomize phase while keeping spectrum magnitude unchanged - and has achieved it. All that remains is to plot the spectrum.

def plot(x0, x1, title):
plt.plot(x0)
plt.plot(x1)
plt.title(title, weight='bold', fontsize=16, loc='left')
plt.show()

plot(amp, np.abs(nft), title="RFFT, original vs new | magnitude")
plot(phi_old, phi_new, title="RFFT, original vs new | phase")

• thank you so much, I am unable to upvote since my "reputation" aint 15 or something, also, just for the sake of knowledge, if I were to shift or stretch this plot along the x-axis within some given range, could you tell me how I could achieve that?
– Modl
Jun 19 '21 at 10:04
• @Modl Stretching the plot is easy; plt.xlims() - the signal another story, its own question. If this answers your original question on phase and magnitude, you can accept the answer. Jun 19 '21 at 11:35

Why does my amplitude change upon inverse Fourier Transform...?

Because sines and cosines don't work the way you seem to think. Here's a really simple case -- $$\sin \omega t \pm \frac{\sin 3\omega t}{3}$$. One plot is the sum, one plot is the difference. Note that the two plots are of markedly different shape -- just from changing the phase of one of the components by 180 degrees.

I just wish to change the shift the plot ... without altering the y-values

You need to study the properties of the Fourier transform. I'm going to put this into the language of the discrete Fourier transform, but there's analogous rules for the continuous Fourier transform. When you shift a time series by $$k$$ samples, you shift the phase of the frequency-domain points by $$\phi_n = - \frac{2 k \pi}{N}$$, where $$N$$ is the number of samples in your set.

I just wish to ... change it's frequency, without altering the y-values

You need to study the properties of the Fourier transform. It's not clear exactly what you mean, but I suspect you want to upsample or downsample the data (i.e., you want the same shape, but longer or shorter).

To make the thing longer when you perform the inverse Fourier transform, add samples to the middle of the Fourier transform series, symmatrically around $$\frac{N}{2}$$. Note that this may have -- interesting -- artifacts unless the higher-frequency components of your spectrum were already zero.

To make the thing shorter when you perform the inverse Fourier transform, trim samples out of the middle, symmatrically around $$\frac{N}{2}$$. If those samples aren't zero, or very very small, odd things will happen.

If you want to modulate the thing onto a carrier -- clarify your question.