Skip to content

Commit 753479e

Browse files
authored
Merge pull request #142 from SciML/faster_results
Faster equation recovery for implict and explicit sindy results
2 parents 7483f0d + 42ab121 commit 753479e

File tree

3 files changed

+62
-56
lines changed

3 files changed

+62
-56
lines changed

src/sindy/isindy.jl

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ function ImplicitSparseIdentificationResult(coeff::AbstractArray, equations::Bas
146146
ps = [p; p_]
147147

148148
= b_(X, ps, t)
149-
training_error = norm.(eachrow(Y-), 2)
149+
training_error = [norm(Y[i, :]-[i,:], 2) for i in 1:size(Ŷ, 1)]
150150
aicc = similar(training_error)
151151

152152
for i in 1:length(aicc)
@@ -158,49 +158,53 @@ end
158158

159159

160160
function derive_implicit_parameterized_eqs::AbstractArray{T, 2}, b::Basis) where T <: Real
161+
162+
sparsity = Int64(norm(Ξ, 0)) # Overall sparsity
163+
@parameters p[1:sparsity]
164+
size_b = length(b)
161165

162-
sparsity = Int64(norm(Ξ, 0))
166+
inds = @. ! iszero)
163167

164-
@parameters p[1:sparsity]
165-
p_ = zeros(eltype(Ξ), sparsity)
168+
pinds = Int64.(norm.(eachcol(inds), 0))
169+
170+
pinds_d = Int64.(norm.(eachcol(inds[1:size_b,:]), 0))
171+
pinds_n = Int64.(norm.(eachcol(inds[size_b+1:end, :]), 0))
172+
173+
p_ = similar(Ξ[inds])
174+
175+
eq = zeros(Operation, sum([i>0 for i in pinds]))
166176
cnt = 1
177+
p_cnt = 1
178+
eq_n = ModelingToolkit.Constant(0)
179+
eq_d = ModelingToolkit.Constant(0)
167180

168-
b_ = Basis(Operation[], variables(b), parameters = [parameters(b)...; p...])
169-
170-
for i=1:size(Ξ, 2)
171-
eq_d = nothing
172-
eq_n = nothing
173-
# Denominator
174-
for j = 1:length(b)
175-
if !iszero(Ξ[j,i])
176-
if eq_d === nothing
177-
eq_d = p[cnt]*b[j]
178-
else
179-
eq_d += p[cnt]*b[j]
181+
@views for i=1:size(Ξ, 2)
182+
# Numerator
183+
eq_n = ModelingToolkit.Constant(0)
184+
eq_d = ModelingToolkit.Constant(0)
185+
if iszero(pinds_n[i]) || iszero(pinds_d[i])
186+
continue
187+
else
188+
for j in 1:size_b
189+
if inds[j, i]
190+
eq_d += p[p_cnt] * b.basis[j]
191+
p_[p_cnt] = Ξ[j, i]
192+
p_cnt += 1
180193
end
181-
p_[cnt] = Ξ[j,i]
182-
cnt += 1
183-
end
184-
end
185194

186-
# Numerator
187-
for j = 1:length(b)
188-
if !iszero(Ξ[j+length(b),i])
189-
if eq_n === nothing
190-
eq_n = p[cnt]*b[j]
191-
else
192-
eq_n += p[cnt]*b[j]
195+
if inds[j+size_b, i]
196+
eq_n += p[p_cnt] * b.basis[j]
197+
p_[p_cnt] = Ξ[j+size_b, i]
198+
p_cnt += 1
193199
end
194-
p_[cnt] = Ξ[j+length(b),i]
195-
cnt += 1
196200
end
197-
end
198201

199-
if !(isnothing(eq_d) || isnothing(eq_n))
200-
push!(b_, ModelingToolkit.simplify(-eq_n ./ eq_d))
202+
eq[cnt] = - eq_n / eq_d
201203
end
202-
204+
cnt += 1
203205
end
204-
206+
207+
b_ = Basis(eq, variables(b), parameters = vcat(parameters(b), p), iv = independent_variable(b))
208+
205209
b_, p_
206210
end

src/sindy/results.jl

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -89,27 +89,29 @@ end
8989

9090
function derive_parameterized_eqs::AbstractArray{T, 2}, b::Basis, sparsity::Int64) where T <: Real
9191
@parameters p[1:sparsity]
92-
p_ = zeros(eltype(Ξ), sparsity)
92+
93+
inds = @. ~ iszero.(Ξ)
94+
p_ = Ξ[inds]
95+
pinds = Int64.(norm.(eachcol(inds), 0))
96+
9397
cnt = 1
94-
b_ = Basis(Operation[], variables(b), parameters = [parameters(b)...; p...], iv = independent_variable(b))
95-
96-
for i=1:size(Ξ, 2)
97-
eq = nothing
98-
for j = 1:size(Ξ, 1)
99-
if !iszero(Ξ[j,i])
100-
if eq === nothing
101-
eq = p[cnt]*b[j]
102-
else
103-
eq += p[cnt]*b[j]
104-
end
105-
p_[cnt] = Ξ[j,i]
106-
cnt += 1
107-
end
108-
end
109-
if !isnothing(eq)
110-
push!(b_, eq)
98+
eq = zeros(Operation, sum([i>0 for i in pinds]))
99+
100+
@inbounds for i=1:size(Ξ, 2)
101+
if iszero(pinds[i])
102+
continue
103+
elseif i == 1
104+
eq[cnt] = sum(p[1:pinds[i]] .* b.basis[inds[:, i]])
105+
cnt += 1
106+
else
107+
eq[cnt] = sum(p[sum(pinds[1:i-1])+1:pinds[i]+sum(pinds[1:i-1])] .* b.basis[inds[:, i]])
108+
cnt += 1
111109
end
110+
111+
112112
end
113+
b_ = Basis(eq, variables(b), parameters = vcat(parameters(b),p), iv = independent_variable(b))
114+
113115
b_, p_
114116
end
115117

test/isindy.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
estimator = ODEProblem(dudt, u0, tspan, ps)
5555
sol_ = solve(estimator, Tsit5(), saveat = 0.1)
5656
@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])
57+
@test abs.(ps) abs.(Float64[1/3, 1.0, 1/3, 2/3, 1, 0.5, 0.5, 1, 1, 1, 1]) atol = 1e-2
5858

5959

6060
@info "Michaelis-Menten-Kinetics"
@@ -90,7 +90,7 @@
9090
estimator = ODEProblem(dudt, u0, tspan, ps)
9191
sol_ = solve(estimator, Tsit5(), saveat = 0.1)
9292
@test isapprox(sol_[:,:], solution_1[:,:], atol = 1e-1)
93-
@test abs.(ps) [1/3; 1.0; 0.2; 0.92] atol = 1e-1
93+
@test abs.(ps) [1/3; 0.2; 1.0; 0.92] atol = 1e-1
9494

9595
Ψ = ISINDy(X, DX, basis, STRRidge(1e-2), maxiter = 100, normalize = true)
9696
print_equations(Ψ, show_parameter = true)
@@ -101,7 +101,7 @@
101101
estimator = ODEProblem(dudt, u0, tspan, ps)
102102
sol_ = solve(estimator, Tsit5(), saveat = 0.1)
103103
@test isapprox(sol_[:,:], solution_1[:,:], atol = 1e-1)
104-
@test abs.(ps) [1/3; 1.0; 0.2; 0.92] atol = 1e-1
104+
@test abs.(ps) [1/3; 0.2; 1.0; 0.92] atol = 1e-1
105105

106106
λs = exp10.(-3:0.1:-1)
107107
Ψ = ISINDy(X, DX, basis, λs ,STRRidge(1e-2), maxiter = 100, normalize = false)
@@ -113,5 +113,5 @@
113113
estimator = ODEProblem(dudt, u0, tspan, ps)
114114
sol_ = solve(estimator, Tsit5(), saveat = 0.1)
115115
@test isapprox(sol_[:,:], solution_1[:,:], atol = 1e-1)
116-
@test abs.(ps) [1/3; 1.0; 0.2; 0.92] atol = 1e-1
116+
@test abs.(ps) [1/3; 0.2; 1.0; 0.92] atol = 1e-1
117117
end

0 commit comments

Comments
 (0)