As the title says, I want to estimate the time periods of a certain kind of oscillation that comes out of an ODE solution:
This behaviour has a large period among other smaller ones (in this image, the time period of the slow modulation is around 70 units) and I want to estimate this time period numerically.
I cannot use a visual estimate (like I did here) because I want to vary a certain parameter (F) in the problem and find out how the slowly varying period depends on the said parameter - so, I need to solve the DE in a loop. If I had a way to estimate the time period from the ODE solution set, I couldāve saved it into a vector or array for each run of the loop and plotted them afterwards to get the dependence.
I tried estimate_period()
from ChaosTools.jl with lombscargle
initially - but this gives me the smaller periods and not the one I want. I know Fourier transforms are usually used to decompose signals but I am not in the field of signal processing and am unfamiliar with this kind of usage.
I tried the FFTW.jl package but its going over my head (mostly because the documentation seems to lack examples) - even then I tried a simple code:
using Symbolics, Plots, DifferentialEquations, ModelingToolkit, LaTeXStrings, Measures, EasyModelAnalysis, CurveFit, ChaosTools, DSP, FFTW
@variables t x(t) y(t)
@parameters F, Ļ
d = Differential(t)
Eā = d(d(x)) + Ļ^2*sin(x)
Eāā = Symbolics.solve_for(Eā ~ Ļ^2*F*cos(Ļ*t), d(d(x)))
system = [d(d(x)) ~ Eāā]
@named model = ODESystem(system, t, [x], [F, Ļ])
model = structural_simplify(model)
X = ODEProblem(model, u_1, (0, 100), [Ļ => 1, F => 0.1])
Y = solve(X, Rodas4P())
v1 = Y[2,:]
v2 = Y[1,:]
Fal = fft(v1) |> fftshift
freqs = fftfreq(length(Y.t)) |> fftshift
plot(freqs, @. abs(Fal))
This gives me:
I have no idea which of these peaks I want (Iād guess the ones closest to 0 since that should have the largest time period - but that is around 0.003 which gives me a time period of 1/0.003 \sim 333 units which is completely wrong). The farthest peaks are correspond to 100 time units as well - much larger than the visual estimate. So, my code must be wrong.
I would like to know if thereās a way to systematically do something like this - any help would be really appreciated!