My aim is to create a surrogate time-series out of an empirically observed time-series where I would like to keep the autocorrelation and power distribution in the frequency-domain, but randomize the the phases.
The steps to achieve this task are as follows:
- The Fourer series of the time-series has to be created
- The phases of the Fourier components are then randomized
- The frequency-domain results are transformed back into the time-domain
Here is the current status of my code where a random time-series is created for means or reproducibility.
import numpy as np
TS = np.random.normal(0, 1, 3000) # The time-series
FFT = np.fft.rfft # FFT of time-series
Random_phases = np.exp(np.random.uniform(0,np.pi,len(TS)/2 1)*1.0j) # Generate random phases
FFT = FFT * Random_phases # Randomize the phases in the FFT
TS = np.fft.irfft(FFT) # Tranforms the frequency-domain back into the time-domain = Surrogate time-series
I am stuck with the following error the code prints:
Traceback (most recent call last):
File "/Users/...", line 7, in <module>
Random_phases = np.exp(np.random.uniform(0,np.pi,len(TS)/2 1)*1.0j) # Generate random phases
File "mtrand.pyx", line 1121, in numpy.random.mtrand.RandomState.uniform
File "_common.pyx", line 615, in numpy.random._common.cont
TypeError: 'float' object cannot be interpreted as an integer
I understand that line 7 of the code Random_phases = np.exp(np.random.uniform(0,np.pi,len(TS)/2 1)*1.0j)
somewhere in the computation produces float instead of integer results, and that this leads to the problem. Is that correct?
What would be an option to overcome this problem without disturbing the actual randomization of the phases in the frequency-domain?
CodePudding user response:
len(TS)/2 1
is a float, while uniform
expects an int for the size
parameter. Try int(len(TS)/2 1)
or len(TS)//2 1
np.fft.rfft
is just the function, which you are not calling as it stands. Presumably you want to call it using the time series, i.e. np.fft.rfft(TS)
.
Putting everything together:
FFT = np.fft.rfft(TS) # FFT of time-series
Random_phases = np.exp(np.random.uniform(0,np.pi,len(TS)//2 1)*1.0j) # Generate random phases
FFT = FFT * Random_phases # Randomize the phases in the FFT
TS = np.fft.irfft(FFT) # Tranforms the frequency-domain back into the time-domain = Surrogate time-series