using Dierckx
using ParameterizedFunctions
using Distributions, Compat
using StatsBase
using MultivariateStats
using StaticArrays, BenchmarkTools
using DifferentialEquations
using LinearAlgebra
using Plots
using Images
using Random
using ODE
rng = MersenneTwister(1234);
using DataDrivenDiffEq
using ModelingToolkit
using DiffEqSensitivity
function pendulum(u, p, t)
x = u[2]
y = -9.81sin(u[1]) - 0.1u[2]
return [x;y]
end
u0 = [0.4π; 1.0]
tspan = (0.0, 20.0)
problem = ODEProblem(pendulum, u0, tspan)
solution = solve(problem, Tsit5(), atol = 1e-8, rtol = 1e-8, saveat = 0.001)
X = Array(solution)
DX = solution(solution.t, Val{1});
plot(X[1,:])
plot!(X[2,:])
@variables u[1:2]
h = Operation[u; u.^2; u.^3; sin.(u); cos.(u); 1]
basis = Basis(h, u)
opt = SR3(3e-1, 1.0)
Ψ = SInDy(X[:, 1:1000], DX[:, 1:1000], basis, maxiter = 10000, opt = opt, normalize = true)
sys = ODESystem(Ψ)
p = parameters(Ψ)
dudt = ODEFunction(sys)
estimator = ODEProblem(dudt, u0, tspan, p)
estimation = solve(estimator, Tsit5(), saveat = solution.t);
Xest=Array(estimation)
println(Ψ)
plot(X[1,:])
plot!(X[2,:])
plot!(Xest[1,:],linestyle = :dash)
plot!(Xest[2,:],linestyle = :dash)
# Differential equations describing the system
function double_pendulum(du,u,p,t)
# du = derivatives
# u = variables
# p = parameters
# t = time variable
m1 = p[1];
m2 = p[2];
L1 = p[3];
L2 = p[4];
g = p[5];
c = cos(u[1]-u[3]); # intermediate variables
s = sin(u[1]-u[3]); # intermediate variables
du[1] = u[2]; # d(theta 1)
du[2] = ( m2*g*sin(u[3])*c - m2*s*(L1*c*u[2]^2 + L2*u[4]^2) - (m1+m2)*g*sin(u[1]) ) /( L1 *(m1+m2*s^2) );
du[3] = u[4]; # d(theta 2)
du[4] = ((m1+m2)*(L1*u[2]^2*s - g*sin(u[3]) + g*sin(u[1])*c) + m2*L2*u[4]^2*s*c) / (L2 * (m1 + m2*s^2));
end
m1 = 1; # mass of pendulum 1 (in kg)
m2 = 1; # mass of pendulum 2 (in kg)
l1 = 1; # length of pendulum 1 (in meter)
l2 = 1; # length of pendulum 2 (in meter)
g = 9.8; # gravitatioanl acceleration constant (m/s^2)
duration = 20.0;
dt = 0.001;
u0 = [pi/2; 0;pi/2; 0]; # initial conditions.
# u[1] = angle of the first pendulum
# u[2] = angular velocity of the first pendulum
# u[3] = angle of the second pendulum
# u[4] = angular velocity of the second pendulum
tfinal = duration; # Final time. Simulation time = 0 to tfinal.
# Solving the system
p = [m1; m2; l1; l2; g];
tspan = (0.0,tfinal); # Time span (limits). The actual time variable is automatically set by solve().
problem = ODEProblem(double_pendulum,u0,tspan,p);
solution = solve(problem,Vern7(),saveat=dt);
# sol[1,:] = u1 = Θ_1
# sol[2,:] = u2 = ω_1
# sol[3,:] = u3 = Θ_2
# sol[4,:] = u4 = ω_2
#sol.t = t = time variable. The ODE solver automatically chooses the time steps.
ph1 = solution[1,:]
ph1dot = solution[2,:]
ph2 = solution[3,:]
ph2dot = solution[4,:]
# anim=plotSolution(solution,p)
# gif(anim,fps=10)
solution = solve(problem, Tsit5(), saveat = dt)
X = Array(solution)
DX = solution(solution.t, Val{1});
plot(X[1,:])
plot!(X[2,:])
plot!(X[3,:])
plot!(X[4,:])
X[:, 1:length(solution.t)]
u0
DX[:, 1:length(solution.t)]
@variables u[1:4]
h = Operation[u; sin.(u); cos.(u); sin.(u.^2); cos.(u.^2); 1]
basis = Basis(h, u)
opt = SR3(3e-1, 1.0)
Ψ = SInDy(X[:, :], DX[:, :], basis, maxiter = 1000000, opt = opt, normalize = true)
println(Ψ)
sys = ODESystem(Ψ)
p = parameters(Ψ)
dudt = ODEFunction(sys)
estimator = ODEProblem(dudt, u0, tspan, p)
estimation = solve(estimator, Tsit5(), saveat = solution.t);
Xest=Array(estimation)
println(Ψ)
plot(X[1,1:10000])
plot!(X[2,1:10000])
# plot!(X[3,:])
# plot!(X[4,:])
plot!(Xest[1,1:10000],linestyle = :dash)
plot!(Xest[2,1:10000],linestyle = :dash)
# plot!(Xest[3,:],linestyle = :dash)
# plot!(Xest[4,:],linestyle = :dash)