-
-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to reconstruct system from result #432
Comments
Yes! I'll work on that. I just ported the necessary stuff right now, but this is a good point. I think you need to unwrap the |
Thanks. I can confirm that the method in the previous doc worked with the previous version of the library, but it doesn't seem to work with v1.0.0. |
I was able to figure it out using using DataDrivenDiffEq
using LinearAlgebra
using OrdinaryDiffEq
using DataDrivenSparse
using StableRNGs
using Symbolics
using Plots
rng = StableRNG(1337)
function pendulum(u, p, t)
x = u[2]
y = -9.81sin(u[1]) - 0.3u[2]^3 - 3.0 * cos(u[1]) - 10.0 * exp(-((t - 5.0) / 5.0)^2)
return [x; y]
end
u0 = [0.99π; -1.0]
tspan = (0.0, 15.0)
prob = ODEProblem(pendulum, u0, tspan)
sol = solve(prob, Tsit5(), saveat = 0.01);
X = sol[:, :] + 0.2 .* randn(rng, size(sol));
ts = sol.t;
prob = ContinuousDataDrivenProblem(X, ts, GaussianKernel(),
U = (u, p, t) -> [exp(-((t - 5.0) / 5.0)^2)],
p = ones(2))
@parameters t
@variables u(t)[1:2] c(t)[1:1]
@parameters w[1:2]
u = collect(u)
c = collect(c)
w = collect(w)
h = Num[sin.(w[1] .* u[1]); cos.(w[2] .* u[1]); polynomial_basis(u, 5); c]
basis = Basis(h, u, parameters = w, controls = c);
println(basis) # hide
sampler = DataProcessing(split = 0.8, shuffle = true, batchsize = 30, rng = rng)
λs = exp10.(-10:0.1:0)
opt = STLSQ(λs)
res = solve(prob, basis, opt,
options = DataDrivenCommonOptions(data_processing = sampler, digits = 1))
system = get_basis(res)
params = get_parameter_map(system)
equations(system)
println(system) # hide
println(params) # hide
t = Symbolics.unwrap(get_iv(system))
subs_control = Dict(
c[1] => exp(-((t - 5.0) / 5.0)^2)
)
eqs = map(equations(system)) do eq
eq.lhs ~ substitute(eq.rhs, subs_control)
end
@named sys = ODESystem(
eqs,
get_iv(system),
states(system),
parameters(system)
);
x0 = [u[1] => u0[1], u[2] => u0[2]]
ps = get_parameter_map(system)
ode_prob = ODEProblem(sys, x0, tspan, ps)
estimate = solve(ode_prob, Tsit5(), saveat = prob.t);
plot(estimate) |
When following this SINDy example, a logical final step would be to run a simulation with the discovered system of equations to inspect the result that it gives. One of the steps to do this would be to replace
c[1]
(the placeholder value for the forcing function) with the actual forcing function in the resulting equations. From a previous version of the documentation that seems like it may have disappeared, it seems that the way to do this would be something like:However, this gives the error
ERROR: MethodError: <ₑ(::Num, ::SymbolicUtils.Mul{Real, Int64, Dict{Any, Number}, Nothing}) is ambiguous. Candidates: <ₑ(a::Number, b::SymbolicUtils.Symbolic) in SymbolicUtils at /.../.julia/packages/SymbolicUtils/qulQp/src/ordering.jl:9
Does anyone have any suggestions of how to fix this? Thanks!
The text was updated successfully, but these errors were encountered: