def find_frequency_response(arg): lamb = arg[0] omegaC = arg[1] K = 10.**5 omegaF = 1000. dt = 10**-5 if omegaC < 50.: save_dt = 10**-4 else: save_dt = 10**-5 # here the convergence rate is too slow - leads to large transcient if lamb < 1.: min_time = 200. else: min_time = 100. max_time = 10000. print("processing lambda = " + str(lamb) + " and omegaC = " + str(omegaC)) oscill = pyafos.PhaseAFO() oscill.initialize(K, lamb) oscill.input().frequency_changing_sine(omegaF, omegaC) # set initial conditions # we want to measure at least 50 oscillations of omegaC # 50 * 2pi/omegaC t_end = np.min([np.max([50 * 2 * np.pi / omegaC, min_time]), max_time]) t_start = 0. omega0 = (omegaF + 1.) / lamb phi0 = 0. pyafos.integrate(oscill, t_start, t_end, np.array([phi0, omega0]), dt, save_dt) omega = lamb * oscill.y()[1, :] t = oscill.t() mins, maxs = find_envelop(omega) n_min = mins[:, 1].size n_max = maxs[:, 1].size if n_min < n_max: track = 0.5 * (mins[:, 1] + maxs[:-(n_max - n_min), 1]) track_signal = omegaF + np.cos(omegaC * t[mins.astype(int)[:, 0]]) elif n_min == n_max: track = 0.5 * (mins[:, 1] + maxs[:, 1]) track_signal = omegaF + np.cos(omegaC * t[mins.astype(int)[:, 0]]) else: track = 0.5 * (mins[:, 1] + maxs[:-(n_min - n_max), 1]) track_signal = omegaF + np.cos(omegaC * t[maxs.astype(int)[:, 0]]) # we get rid of the first half of the signal, make sure no transcients are here track = track[int(track.size / 2):] track_signal = track_signal[int(track_signal.size / 2):] response = scipy.signal.hilbert( track - np.mean(track)) / scipy.signal.hilbert(track_signal - omegaF) # we only keep the middle third of the response to remove boarder effects si = response.size am = np.mean(np.abs(response[int(si / 3):int(2 * si / 3)])) #to make sure all is close to each other angle = np.unwrap(np.angle(response[int(si / 3):int(2 * si / 3)])) ph = np.mean(angle - 2 * np.pi) % (-2 * np.pi) if np.abs(ph) > 1.8 * np.pi: ph = ph + 2 * np.pi # ph = np.mean((np.angle(response[int(si/3):int(2*si/3)]) - 2 * np.pi))%(-2*np.pi) print("done with lambda = " + str(lamb) + " and omegaC = " + str(omegaC) + "found " + str(am) + " " + str(ph)) # amplitude[i,j] = am # phase[i,j] = ph return am, ph
K = 10.**6 omegaF = 30. freq = omegaF * np.array([1., 2., 3.]) amp = np.array([1.3, 1., 1.4]) phase = np.array([0.4, 0.0, 1.3]) + np.pi / 2.0 lamb = 1 dt = 10**-7 save_dt = 10**-3 t_end = 8. t_start = 0. omega0 = 20. / lamb phi0 = 0. #run an integration oscill = pyafos.PhaseAFO() oscill.initialize(K, lamb) oscill.input().vec_of_sines(freq, amp, phase) pyafos.integrate(oscill, t_start, t_end, np.array([phi0, omega0]), dt, save_dt) #get the data to be plotted t = oscill.t() phi = oscill.y()[0, :] omega = oscill.y()[1, :] deltaT = np.linspace(0.0, 2 * pi / omegaF, 10000) roots = find_roots(deltaT, freq, amp, phase) roots_corrected = roots + (2. * pi / omegaF - roots[-1]) n_roots = size(roots) print('num roots is ', n_roots) print('roots ', roots)