Skip to content

Commit 8b323c3

Browse files
authored
Merge pull request #138 from SciML/AlCap23-patch-2
Update docs and release version
2 parents 2a65089 + 3ec76b2 commit 8b323c3

File tree

4 files changed

+63
-63
lines changed

4 files changed

+63
-63
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "DataDrivenDiffEq"
22
uuid = "2445eb08-9709-466a-b3fc-47e12bd697a2"
33
authors = ["Julius Martensen <[email protected]>"]
4-
version = "0.3.2"
4+
version = "0.3.3"
55

66
[deps]
77
Compat = "34da2185-b29b-5c13-b0c7-acf172513d20"

docs/src/sparse_identification/isindy.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Implicit Sparse Identification of Nonlinear Dynamics
22

3-
While `SInDy` works well for ODEs, some systems take the form of rational functions `dx = f(x) / g(x)`. These can be inferred via `ISInDy`, which extends `SInDy` [for Implicit problems](https://ieeexplore.ieee.org/abstract/document/7809160). In particular, it solves
3+
While `SInDy` works well for ODEs, some systems take the form of [DAE](https://diffeq.sciml.ai/stable/types/dae_types/)s. A common form is `f(x, p, t) - g(x, p, t)*dx = 0`. These can be inferred via `ISInDy`, which extends `SInDy` [for Implicit problems](https://ieeexplore.ieee.org/abstract/document/7809160). In particular, it solves
44

55
```math
66
\Xi = \min ~ \left\lVert \Theta(X, p, t)^{T} \Xi \right\rVert_{2} + \lambda ~ \left\lVert \Xi \right\rVert_{1}
@@ -90,7 +90,7 @@ The parameters are off a little, but, as before, we can use `DiffEqFlux` to tune
9090

9191
## Example : Cart-Pole with Time-Dependent Control
9292

93-
Implicit dynamics can also be reformulated as an explicit problem as stated in [this paper](https://arxiv.org/pdf/2004.02322.pdf). The algorithm tries to find the right equations by trying out all candidate functions as a right hand side and performing a sparse regression onto the remaining set of candidates. Let's start by defining the problem and generate the data:
93+
Implicit dynamics can also be reformulated as an explicit problem as stated in [this paper](https://arxiv.org/pdf/2004.02322.pdf). The algorithm searches the correct equations by trying out all candidate functions as a right hand side and performing a sparse regression onto the remaining set of candidates. Let's start by defining the problem and generate the data:
9494

9595
```@example isindy_2
9696
@@ -130,7 +130,8 @@ savefig("isindy_cartpole_data.png") # hide
130130
```
131131
![](isindy_cartpole_data.png)
132132

133-
As always, we will also need a `Basis` to derive our equations from:
133+
We see that we include a forcing term `F` inside the model which is depending on `t`.
134+
As before, we will also need a `Basis` to derive our equations from:
134135

135136
```@example isindy_2
136137
@variables u[1:4] t
@@ -161,7 +162,9 @@ basis= Basis(polys, u, iv = t)
161162

162163
We added the time dependent input directly into the basis to account for its influence.
163164

164-
Like for a normal sparse regression, we can use any `AbstractOptimizer` with a pareto front optimization over different thresholds.
165+
*NOTE : Including input signals may change in future releases!*
166+
167+
Like for a `SInDy`, we can use any `AbstractOptimizer` with a pareto front optimization over different thresholds.
165168

166169
```@example isindy_2
167170
λ = exp10.(-4:0.1:-1)
@@ -177,14 +180,13 @@ ps = parameters(Ψ)
177180
estimator = ODEProblem(dudt, u0, tspan, ps)
178181
sol_ = solve(estimator, Tsit5(), saveat = dt)
179182
180-
# Yeah! We got it right
181183
plot(solution.t[:], solution[:,:]', color = :red, label = nothing) # hide
182184
plot!(sol_.t, sol_[:, :]', color = :green, label = "Estimation") # hide
183185
savefig("isindy_cartpole_estimation.png") # hide
184186
```
185187
![](isindy_cartpole_estimation.png)
186188

187-
Let's have a look at the equations recovered.
189+
Let's have a look at the equations recovered. They nearly match up.
188190

189191
```@example isindy_2
190192
print_equations(Ψ)

src/sindy/isindy.jl

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
Performs an implicit sparse identification of nonlinear dynamics given the data matrices `X` and `Y` via the `AbstractBasis` `basis.`
1515
Keyworded arguments include the parameter (values) of the basis `p` and the timepoints `t`, which are passed in optionally.
1616
Tries to find a sparse vector inside the nullspace if `opt` is an `AbstractSubspaceOptimizer` or performs parallel implicit search if `opt` is a `AbstractOptimizer`.
17-
`maxiter` the maximum iterations to perform and `convergence_error` the
17+
`maxiter` denote the maximum iterations to perform and `convergence_error` the
1818
bound which causes the optimizer to stop. `denoise` defines if the matrix holding candidate trajectories should be thresholded via the [optimal threshold for singular values](http://arxiv.org/abs/1305.5870).
1919
`normalize` normalizes the matrix holding candidate trajectories via the L2-Norm over each function.
2020
@@ -145,8 +145,6 @@ function ImplicitSparseIdentificationResult(coeff::AbstractArray, equations::Bas
145145
b_, p_ = derive_implicit_parameterized_eqs(coeff, equations)
146146
ps = [p; p_]
147147

148-
println(sparsities)
149-
println(b_)
150148
= b_(X, ps, t)
151149
training_error = norm.(eachrow(Y-Ŷ), 2)
152150
aicc = similar(training_error)

test/isindy.jl

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,59 @@
22
@info "Starting implicit SINDy tests"
33
@testset "ISInDy" begin
44

5-
#@info "Nonlinear Implicit System"
6-
## Create a test problem
7-
#function simple(u, p, t)
8-
# return [(2.0u[2]^2 - 3.0)/(1.0 + u[1]^2); -u[1]^2/(2.0 + u[2]^2); (1-u[2])/(1+u[3]^2)]
9-
#end
10-
#
11-
#u0 = [2.37; 1.58; -3.10]
12-
#tspan = (0.0, 10.0)
13-
#prob = ODEProblem(simple, u0, tspan)
14-
#sol = solve(prob, Tsit5(), saveat = 0.1)
15-
#
16-
## Create the differential data
17-
#X = sol[:,:]
18-
#DX = similar(X)
19-
#for (i, xi) in enumerate(eachcol(X))
20-
# DX[:, i] = simple(xi, [], 0.0)
21-
#end
22-
#
23-
## Create a basis
24-
#@variables u[1:3]
25-
#polys = ModelingToolkit.Operation[]
26-
## Lots of basis functions
27-
#for i ∈ 0:5
28-
# if i == 0
29-
# push!(polys, u[1]^0)
30-
# end
31-
# for ui in u
32-
# if i > 0
33-
# push!(polys, ui^i)
34-
# end
35-
# end
36-
#end
37-
#
38-
#basis= Basis(polys, u)
39-
#
40-
#opt = ADM(1e-2)
41-
#Ψ = ISInDy(X, DX, basis, opt = opt, maxiter = 100)
42-
#
43-
## Transform into ODE System
44-
#sys = ODESystem(Ψ)
45-
#dudt = ODEFunction(sys)
46-
#ps = parameters(Ψ)
47-
#print_equations(Ψ, show_parameter = true)
48-
#
49-
#@test all(get_error(Ψ) .< 1e-6)
50-
#@test length(ps) == 11
51-
#@test get_sparsity(Ψ) == [4; 3; 4]
52-
#
53-
## Simulate
54-
#estimator = ODEProblem(dudt, u0, tspan, ps)
55-
#sol_ = solve(estimator, Tsit5(), saveat = 0.1)
56-
#@test sol[:,:] ≈ sol_[:,:]
57-
#@test abs.(ps) ≈ abs.(Float64[-1/3 ; -1/3 ; -1.00 ; 2/3; 1.00 ;0.5 ;0.5 ; 1.0; 1.0; -1.0; 1.0])
5+
@info "Nonlinear Implicit System"
6+
# Create a test problem
7+
function simple(u, p, t)
8+
return [(2.0u[2]^2 - 3.0)/(1.0 + u[1]^2); -u[1]^2/(2.0 + u[2]^2); (1-u[2])/(1+u[3]^2)]
9+
end
10+
11+
u0 = [2.37; 1.58; -3.10]
12+
tspan = (0.0, 10.0)
13+
prob = ODEProblem(simple, u0, tspan)
14+
sol = solve(prob, Tsit5(), saveat = 0.1)
15+
16+
# Create the differential data
17+
X = sol[:,:]
18+
DX = similar(X)
19+
for (i, xi) in enumerate(eachcol(X))
20+
DX[:, i] = simple(xi, [], 0.0)
21+
end
22+
23+
# Create a basis
24+
@variables u[1:3]
25+
polys = ModelingToolkit.Operation[]
26+
# Lots of basis functions
27+
for i 0:5
28+
if i == 0
29+
push!(polys, u[1]^0)
30+
end
31+
for ui in u
32+
if i > 0
33+
push!(polys, ui^i)
34+
end
35+
end
36+
end
37+
38+
basis= Basis(polys, u)
39+
40+
opt = ADM(1e-2)
41+
Ψ = ISInDy(X, DX, basis, opt, maxiter = 100)
42+
43+
# Transform into ODE System
44+
sys = ODESystem(Ψ)
45+
dudt = ODEFunction(sys)
46+
ps = parameters(Ψ)
47+
print_equations(Ψ, show_parameter = true)
48+
49+
@test all(get_error(Ψ) .< 1e-6)
50+
@test length(ps) == 11
51+
@test get_sparsity(Ψ) == [4; 3; 4]
52+
53+
# Simulate
54+
estimator = ODEProblem(dudt, u0, tspan, ps)
55+
sol_ = solve(estimator, Tsit5(), saveat = 0.1)
56+
@test sol[:,:] sol_[:,:]
57+
@test abs.(ps) abs.(Float64[-1/3 ; -1/3 ; -1.00 ; 2/3; 1.00 ;0.5 ;0.5 ; 1.0; 1.0; -1.0; 1.0])
5858

5959

6060
@info "Michaelis-Menten-Kinetics"

0 commit comments

Comments
 (0)