I want to calculate First HPF and then FFT of an acceleration data for which I use the following code.
# Make Function
def filter(s):
# Signal after HPF
fc = 0.1
b = 0.08
N = int(np.ceil((4 / b)))
if not N % 2: N += 1
n = np.arange(N)
sinc_func = np.sinc(2 * fc * (n - (N - 1) / 2.))
window = np.blackman(N)
sinc_func = sinc_func * window
sinc_func = sinc_func / np.sum(sinc_func)
# reverse function
sinc_func = -sinc_func
sinc_func[int((N - 1) / 2)] += 1
#s = list(df[' acc.y'])
new_signal = np.convolve(s, sinc_func)
a=np.fft.fft(new_signal)
return a
The question is this returns an array now I want to calculate the single-valued Magnitude of this Numpy ie I need the Magnitude for the signal whose FFT i calculate
Related
I am trying to use wiener filtering to convert the 824 audio in one folder to a different folder. How can I create a module for accessing these audio, running the wiener and save it to different folder by python? What I am doing right now just convert it one by one. Here's the code:
import numpy as np
import wave
import matplotlib.pyplot as plt
import math
from scipy.io import wavfile
import glob
import tqdm
#import nextpow2
'''
# input wave file (clean)
f1 = wave.open('p232_006.wav')
# read format information
# (nchannels, sampwidth, framerate, nframes, comptype, compname)
params1 = f1.getparams()
nchannels1, sampwidth1, framerate1, nframes1 = params1[:4]
fs1 = framerate1
# read wave data
str_data1 = f1.readframes(nframes1)
# close .wav file
f1.close()
# convert waveform data to an array
x1 = np.fromstring(str_data1, dtype=np.short)
'''
# noisy speech FFT
#x1_FFT = abs(np.fft.fft(x1))
# input wave file (noise)
f = wave.open('p257_434ch0_16k.wav')
#test_wav = sorted(glob.glob("./noisy_testset_wav_16*.wav"))
#for i, (test_wav) in tqdm(enumerate(zip(test_wav))):
# f = wavfile.read(test_wav)
# read format information
# (nchannels, sampwidth, framerate, nframes, comptype, compname)
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
fs = framerate
# read wave data
str_data = f.readframes(nframes)
# close .wav file
f.close()
# convert waveform data to an array
x = np.fromstring(str_data, dtype=np.short)
# noisy speech FFT
x_FFT = abs(np.fft.fft(x))
# calculation parameters
len_ = 20 * fs // 1000 # frame size in samples
PERC = 50 # window overlop in percent of frame
len1 = len_ * PERC // 100 # overlop'length
len2 = len_ - len1 # window'length - overlop'length
# setting default parameters
Thres = 3 # VAD threshold in dB SNRseg
Expnt = 1.0
beta = 0.002
G = 0.9
# hamming window
#win = np.hamming(len_)
# sine window
i = np.linspace(0,len_ - 1,len_)
win = np.sqrt(2/(len_ + 1)) * np.sin(np.pi * (i + 1) / (len_ + 1))
# normalization gain for overlap+add with 50% overlap
winGain = len2 / sum(win)
# nFFT = 2 * 2 ** (nextpow2.nextpow2(len_))
nFFT = 2 * 2 ** 8
noise_mean = np.zeros(nFFT)
j = 1
for k in range(1, 6):
noise_mean = noise_mean + abs(np.fft.fft(win * x[j:j + len_], nFFT))
j = j + len_
noise_mu = noise_mean / 5
# initialize various variables
k = 1
img = 1j
x_old = np.zeros(len1)
Nframes = len(x) // len2 - 1
xfinal = np.zeros(Nframes * len2)
# === Start Processing ==== #
for n in range(0, Nframes):
# Windowing
insign = win * x[k-1:k + len_ - 1]
# compute fourier transform of a frame
spec = np.fft.fft(insign, nFFT)
# compute the magnitude
sig = abs(spec)
# save the noisy phase information
theta = np.angle(spec)
# Posterior SNR
SNRpos = 10 * np.log10(np.linalg.norm(sig, 2) ** 2 / np.linalg.norm(noise_mu, 2) ** 2)
# --- wiener filtering --- #
# 1 spectral subtraction(Half wave rectification)
sub_speech = sig ** Expnt - noise_mu ** Expnt
# When the pure signal is less than the noise signal power
diffw = sig ** Expnt - noise_mu ** Expnt
# beta negative components
def find_index(x_list):
index_list = []
for i in range(len(x_list)):
if x_list[i] < 0:
index_list.append(i)
return index_list
z = find_index(diffw)
if len(z) > 0:
sub_speech[z] = 0
# Priori SNR
SNRpri = 10 * np.log10(np.linalg.norm(sub_speech, 2) ** 2 / np.linalg.norm(noise_mu, 2) ** 2)
# parameter to deal mel
mel_max = 10
mel_0 = (1 + 4 * mel_max) / 5
s = 25 / (mel_max - 1)
# deal mel
def get_mel(SNR):
if -5.0 <= SNR <= 20.0:
a = mel_0 - SNR / s
else:
if SNR < -5.0:
a = mel_max
if SNR > 20:
a = 1
return a
# setting mel
mel = get_mel(SNRpri)
# 2 gain function Gk
#G_k = (sig ** Expnt - noise_mu ** Expnt) / sig ** Expnt
G_k = sub_speech ** 2 / (sub_speech ** 2 + mel * noise_mu ** 2)
#wf_speech = G_k * sub_speech ** (1 / Expnt)
wf_speech = G_k * sig
# --- implement a simple VAD detector --- #
if SNRpos < Thres: # Update noise spectrum
noise_temp = G * noise_mu ** Expnt + (1 - G) * sig ** Expnt # Smoothing processing noise power spectrum
noise_mu = noise_temp ** (1 / Expnt) # New noise amplitude spectrum
# add phase
#wf_speech[nFFT // 2 + 1:nFFT] = np.flipud(wf_speech[1:nFFT // 2])
x_phase = wf_speech * np.exp(img * theta)
# take the IFFT
xi = np.fft.ifft(x_phase).real
# --- Overlap and add --- #
xfinal[k-1:k + len2 - 1] = x_old + xi[0:len1]
x_old = xi[0 + len1:len_]
k = k + len2
# save wave file
wf = wave.open('p257_434.wav','w')
# setting parameter
wf.setparams(params)
# set waveform file .tostring()Convert array touput data
wave_data = (winGain * xfinal).astype(np.short)
wf.writeframes(wave_data.tostring())
# close wave file
wf.close()
# enchanced speech FFT
es_FFT = abs(np.fft.fft(winGain * xfinal))
any help would be appreaciated.
I describe a pulse in the time domain and do a Fourier Transform to convert it to the frequency domain.
I add an e-index polynomial phase e^{i*phase}to it in the frequency domain,phase is a polynomial.
At this time, I use the angle function under numpy to extract the phase, and what I get is such dense peaks as shown in the figure. I don't know if this is correct and I don't know how should I extract the polynomial again.
import numpy as np
import matplotlib.pyplot as plt
fs = 1e-15
THz = 1e12
nm = 1e-9
c = 3e8
N = 2 ** 13
time_window = 3000 * fs
wavelength = 800 * nm
t = np.linspace(-time_window / 2,time_window / 2, N)
df = np.append(np.linspace(0, N / 2, int(N / 2)),(np.linspace(-N / 2, -1, int(N / 2))))/ time_window
f = c/wavelength + df
dw = 2 * np.pi * df
FWHM = 50 * fs
m = 4 * np.log(2)
A_t = np.exp(-m * t ** 2 * (1 / 2) / FWHM ** 2)
A_w = np.fft.fft(A_t)
GDD = 500 * fs*fs
TOD = 0 * fs*fs*fs
FOD = 0
A_w = np.exp(1j * (GDD / 2.0) * dw**2 +
1j * (TOD / 6.0) * dw ** 3+
1j * (FOD / 24.0) * dw ** 4) * A_w
fig_1 = plt.figure(1, facecolor='w', edgecolor='k')
ax_1 = fig_1.add_subplot(1, 1, 1)
ax_2 = ax_1.twinx()
ax_1.plot(np.fft.fftshift(f/THz),np.fft.fftshift(np.abs(A_w) ** 2 / max(np.abs(A_w) ** 2)),'b')
ax_2.plot(np.fft.fftshift(f/THz),np.fft.fftshift(np.angle(A_w)),'r')
ax_1.set_ylabel('Intensity / a.u.')
ax_2.set_ylabel('Phase / rad')
ax_1.tick_params(axis='y', colors='b')
ax_2.tick_params(axis='y', colors='r')
plt.xlim(300,450)
plt.show()
Two things. To center your data relative to phase, you need to either fftshift your data before the FFT, or flip the sign of the imaginary component in every other result element.
Then look at the magnitude result. When the magnitudes go sufficiently near zero, the phase becomes that of random numerical noise, rather than informative. So the phase of near zero magnitudes can be zeroed to make the plot look cleaner.
I have a given power spectral density function of a wind excitation. In order to find my covariance function, I am using the irfft function in python. However, the covariance function is weirdly mirrored at about x = 5.
Here is my code.
def to_time_domain(x, y):
N = 2*len(x)-1 # Number of samples in the time domain
T = (len(x)-1) / (x[-1]) # observation length in time
sample_rate = N/T
ys =irfft(y*sample_rate/2, N-1)
return ys
# power spectral density of wind
def Gust_induced_vibration( vm, vm_10 ,z ,f, k, alpha, roh = 1.25): #
I_z_quad = 6 * k * (z/10)**(-2* alpha)
v_z = vm_10 * (z/10)**alpha
zeta = 1200 * f/ vm_10
S = (roh * 2 * vm)**2 * I_z_quad * v_z**2 * 2/3 * zeta**2 / ((1 + zeta** 2)**(4/3))
return S
sample_rate = 250 #data point per second --> max. freq: sample_rate/2
T = 10 # observation length
N = sample_rate * T # number of samples
dt = 1/sample_rate #time step
f = rfftfreq(N, 1/sample_rate)
#environmental conditions that influence the excitation
k = 0.02 #city
z = 10 # m
v = 22 # m/s
alpha = 1/np.log(10/0.5) #depends on surface roughness
power_spec = Gust_induced_vibration( v, v, z ,f, k, alpha)
#covariance
cov = to_time_domain(f,power_spec)
t = np.linspace(0, T-dt, sample_rate * T)
plt.plot(t, cov)
plt.show()
The plot of the covariance function looks as following.
Plot of covariance
I am grateful for every tip!
I'm trying to approximate the European call option price of the Black-Scholes model (PDE) by the explicit finite difference method in python. For reference, the exact solution using the Black-Scholes formula is 10.247013813310648
Here is a link about the PDE Black-Scholes Equation and the discretized version of the equation can be found here Explicit finite difference method for Black-Scholes model
Can anyone point out why I'm not getting an approximation?
import numpy as np
# Terminal time
T = 0.25
# Strike price
K = 10
# risk free rate
r = 0.1
# volatility (systemic/market risk)
sigma = 0.4
# initial asset value
S0 = 20
# Assume an upper limit for the underlying stock that is 3 - 4 times the exercise price
S_max = 3 * K
# Number of space intervals
M = 200
# space mesh and space step
space_mesh, space_step = np.linspace(0, S_max, M, retstep=True)
# Stability condition
stability_cond = 1 / ( sigma**2 * (M-1) + 0.5* r )
# Find the number of time intervals and time steps that satisfy the stability condition
for percentage in np.arange(.99, .0001, -.0001):
time_step = np.round(percentage * stability_cond, 6)
N = T / time_step
if N.is_integer():
print("Number of time intervals = ", N," ", "time step = ", time_step)
# Choose number of time intervals
N = 2000
# time mesh
time_mesh, time_step = np.linspace(0, T, N, retstep= True)
# time step
time_step = np.round(time_step, 6)
# unknown u at new time level
u = np.zeros(M)
# u at the previous time level
u_prev = np.zeros(M)
# initial condition
for m in range(0, M):
u_prev[m] = np.maximum(space_mesh[m] - K, 0)
# Explicit finite difference scheme
for n in range(0, N):
for m in range(1,M-1):
a = 0.5 * time_step * ( sigma**2 *m**2 - r * m )
b = 1 - time_step * ( sigma**2 * m**2 + r )
c = 0.5 * time_step * ( sigma**2 * m**2 + r * m)
# The discretized version of the Black-Scoles PDE
u[m] = a * u_prev[m-1] + b* u_prev[m] + c * u_prev[m+1]
# insert boundry conditions
u[0] = 0
u[M-1] = S_max
# update u_prev before next iteration
u_prev[:] = u
I came to ask for some help with maths and programming.
What am I trying to do? I'm trying to implement a simulation of a chaotic billiard system, following the algorithm in this excerpt.
How am I trying it? Using numpy and matplotlib, I implemented the following code
def boundaryFunction(parameter):
return 1 + 0.1 * np.cos(parameter)
def boundaryDerivative(parameter):
return -0.1 * np.sin(parameter)
def trajectoryFunction(parameter):
aux = np.sin(beta - phi) / np.sin(beta - parameter)
return boundaryFunction(phi) * aux
def difference(parameter):
return trajectoryFunction(parameter) - boundaryFunction(parameter)
def integrand(parameter):
rr = boundaryFunction(parameter)
dd = boundaryDerivative (parameter)
return np.sqrt(rr ** 2 + dd ** 2)
##### Main #####
length_vals = np.array([], dtype=np.float64)
alpha_vals = np.array([], dtype=np.float64)
# nof initial phi angles, alpha angles, and nof collisions for each.
n_phi, n_alpha, n_cols, count = 10, 10, 10, 0
# Length of the boundary
total_length, err = integrate.quad(integrand, 0, 2 * np.pi)
for phi in np.linspace(0, 2 * np.pi, n_phi):
for alpha in np.linspace(0, 2 * np.pi, n_alpha):
for n in np.arange(1, n_cols):
nu = np.arctan(boundaryFunction(phi) / boundaryDerivative(phi))
beta = np.pi + phi + alpha - nu
# Determines next impact coordinate.
bnds = (0, 2 * np.pi)
phi_new = optimize.minimize_scalar(difference, bounds=bnds, method='bounded').x
nu_new = np.arctan(boundaryFunction(phi_new) / boundaryDerivative(phi_new))
# Reflection angle with relation to tangent.
alpha_new = phi_new - phi + nu - nu_new - alpha
# Arc length for current phi value.
arc_length, err = integrate.quad(integrand, 0, phi_new)
# Append values to list
length_vals = np.append(length_vals, arc_length / total_length)
alpha_vals = np.append(alpha_vals, alpha)
count += 1
print "{}%" .format(100 * count / (n_phi * n_alpha))
What is the problem? When calculating phi_new, the equation has two solutions (assuming the boundary is convex, which is.) I must enforce that phi_new is the solution which is different from phi, but I don't know how to do that. Are there more issues with the code?
What should the output be? A phase space diagram of S x Alpha, looking like this.
Any help is very appreciated! Thanks in advance.
One way you could try would be (given there really are only two solutions) would be
epsilon = 1e-7 # tune this
delta = 1e-4 # tune this
# ...
bnds = (0, 2 * np.pi)
phi_new = optimize.minimize_scalar(difference, bounds=bnds, method='bounded').x
if abs(phi_new - phi) < epsilon:
bnds_1 = (0, phi - delta)
phi_new_1 = optimize.minimize_scalar(difference, bounds=bnds_1, method='bounded').x
bnds_2 = (phi + delta, 2 * np.pi)
phi_new_2 = optimize.minimize_scalar(difference, bounds=bnds_2, method='bounded').x
if difference(phi_new_1) < difference(phi_new_2):
phi_new = phi_new_1
else:
phi_new = phi_new_2
Alternatively, you could introduce a penalty-term, e.g. delta*exp(eps/(x-phi)^2) with appropriate choices of epsilon and delta.