Skip to content
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

feat: handle Initial(x) initialization_eqs in time-independent systems #3466

Merged
merged 17 commits into from
Mar 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
41ce7f5
fix: remove extra print statements
AayushSabharwal Mar 17, 2025
16ac26f
feat: add `Initial` parameters for unknowns to all non-initialization…
AayushSabharwal Mar 17, 2025
d3a5386
feat: handle `Initial(x)` initialization_eqs for time-independent sys…
AayushSabharwal Mar 17, 2025
ff7d28d
test: test `Initial(x)` initialization_eqs for time-independent systems
AayushSabharwal Mar 17, 2025
3e58b5a
Update src/systems/problem_utils.jl
ChrisRackauckas Mar 17, 2025
25159b8
refactor: remove extra empty file
AayushSabharwal Mar 17, 2025
f05b93f
build: bump DiffEqBase compat
AayushSabharwal Mar 18, 2025
d5e3d1a
feat: add `supports_initialization` trait
AayushSabharwal Mar 18, 2025
62b8c3c
fix: only add `Initial` parameters for systems that support initializ…
AayushSabharwal Mar 18, 2025
ca7b9c1
fix: handle cyclic `u0map` in some cases
AayushSabharwal Mar 18, 2025
bc0239c
test: update NonlinearSystem tests with new `Initial` parameters
AayushSabharwal Mar 18, 2025
b5cfedb
test: make hack tests more consistent
AayushSabharwal Mar 19, 2025
beb777a
fix: fix duplicated code running unconditionally
AayushSabharwal Mar 19, 2025
6dc3586
fix: only add observed equations to `u0map` for time-independent or i…
AayushSabharwal Mar 19, 2025
9335a5b
fix: fix `modelingtoolkitize(::NonlinearProblem)`
AayushSabharwal Mar 19, 2025
f276d4c
fix: add `add_additional_parameters` kwarg to `complete`
AayushSabharwal Mar 19, 2025
ec2fbb4
fix: don't add initial parameters in `ODEProblem(::JumpSystem)`
AayushSabharwal Mar 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ DataInterpolations = "6.4"
DataStructures = "0.17, 0.18"
DeepDiffs = "1"
DelayDiffEq = "5.50"
DiffEqBase = "6.157"
DiffEqBase = "6.165.1"
DiffEqCallbacks = "2.16, 3, 4"
DiffEqNoiseProcess = "5"
DiffRules = "0.1, 1.0"
Expand Down
1 change: 0 additions & 1 deletion src/doc

This file was deleted.

64 changes: 26 additions & 38 deletions src/systems/abstractsystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -676,23 +676,27 @@ function SymbolicUtils.maketerm(::Type{<:BasicSymbolic}, ::Initial, args, meta)
return metadata(val, meta)
end

supports_initialization(sys::AbstractSystem) = true

function add_initialization_parameters(sys::AbstractSystem)
@assert !has_systems(sys) || isempty(get_systems(sys))
supports_initialization(sys) || return sys
is_initializesystem(sys) && return sys

all_initialvars = Set{BasicSymbolic}()
# time-independent systems don't initialize unknowns
if is_time_dependent(sys)
eqs = equations(sys)
if !(eqs isa Vector{Equation})
eqs = Equation[x for x in eqs if x isa Equation]
end
obs, eqs = unhack_observed(observed(sys), eqs)
for x in Iterators.flatten((unknowns(sys), Iterators.map(eq -> eq.lhs, obs)))
x = unwrap(x)
if iscall(x) && operation(x) == getindex
push!(all_initialvars, arguments(x)[1])
else
push!(all_initialvars, x)
end
# but may initialize parameters using guesses for unknowns
eqs = equations(sys)
if !(eqs isa Vector{Equation})
eqs = Equation[x for x in eqs if x isa Equation]
end
obs, eqs = unhack_observed(observed(sys), eqs)
for x in Iterators.flatten((unknowns(sys), Iterators.map(eq -> eq.lhs, obs)))
x = unwrap(x)
if iscall(x) && operation(x) == getindex
push!(all_initialvars, arguments(x)[1])
else
push!(all_initialvars, x)
end
end
for eq in parameter_dependencies(sys)
Expand Down Expand Up @@ -722,15 +726,8 @@ Returns true if the parameter `p` is of the form `Initial(x)`.
"""
function isinitial(p)
p = unwrap(p)
if iscall(p)
operation(p) isa Initial && return true
if operation(p) === getindex
operation(arguments(p)[1]) isa Initial && return true
end
else
return false
end
return false
return iscall(p) && (operation(p) isa Initial ||
operation(p) === getindex && isinitial(arguments(p)[1]))
end

"""
Expand All @@ -744,7 +741,8 @@ the global structure of the system.
One property to note is that if a system is complete, the system will no longer
namespace its subsystems or variables, i.e. `isequal(complete(sys).v.i, v.i)`.
"""
function complete(sys::AbstractSystem; split = true, flatten = true)
function complete(
sys::AbstractSystem; split = true, flatten = true, add_initial_parameters = true)
newunknowns = OrderedSet()
newparams = OrderedSet()
iv = has_iv(sys) ? get_iv(sys) : nothing
Expand All @@ -765,7 +763,9 @@ function complete(sys::AbstractSystem; split = true, flatten = true)
@set! newsys.parent = complete(sys; split = false, flatten = false)
end
sys = newsys
sys = add_initialization_parameters(sys)
if add_initial_parameters
sys = add_initialization_parameters(sys)
end
end
if split && has_index_cache(sys)
@set! sys.index_cache = IndexCache(sys)
Expand Down Expand Up @@ -1345,20 +1345,8 @@ function parameters(sys::AbstractSystem; initial_parameters = false)
systems = get_systems(sys)
result = unique(isempty(systems) ? ps :
[ps; reduce(vcat, namespace_parameters.(systems))])
if !initial_parameters
if is_time_dependent(sys)
# time-dependent systems have `Initial` parameters for all their
# unknowns/pdeps, all of which should be hidden.
filter!(x -> !iscall(x) || !isa(operation(x), Initial), result)
else
# time-independent systems only have `Initial` parameters for
# pdeps. Any other `Initial` parameters should be kept (e.g. initialization
# systems)
filter!(
x -> !iscall(x) || !isa(operation(x), Initial) ||
!has_parameter_dependency_with_lhs(sys, only(arguments(x))),
result)
end
if !initial_parameters && !is_initializesystem(sys)
filter!(x -> !iscall(x) || !isa(operation(x), Initial), result)
end
return result
end
Expand Down
2 changes: 2 additions & 0 deletions src/systems/discrete_system/discrete_system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -421,3 +421,5 @@ end
function DiscreteFunctionExpr(sys::DiscreteSystem, args...; kwargs...)
DiscreteFunctionExpr{true}(sys, args...; kwargs...)
end

supports_initialization(::DiscreteSystem) = false
2 changes: 0 additions & 2 deletions src/systems/discrete_system/implicit_discrete_system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -333,10 +333,8 @@ function SciMLBase.ImplicitDiscreteProblem(

u0map = to_varmap(u0map, dvs)
u0map = shift_u0map_forward(sys, u0map, defaults(sys))
@show u0map
f, u0, p = process_SciMLProblem(
ImplicitDiscreteFunction, sys, u0map, parammap; eval_expression, eval_module, kwargs...)
@show u0

kwargs = filter_kwargs(kwargs)
ImplicitDiscreteProblem(f, u0, tspan, p; kwargs...)
Expand Down
4 changes: 3 additions & 1 deletion src/systems/jumps/jumpsystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ function DiffEqBase.ODEProblem(sys::JumpSystem, u0map, tspan::Union{Tuple, Nothi
systems = get_systems(sys), defaults = defaults(sys), guesses = guesses(sys),
parameter_dependencies = parameter_dependencies(sys),
metadata = get_metadata(sys), gui_metadata = get_gui_metadata(sys))
osys = complete(osys)
osys = complete(osys; add_initial_parameters = false)
return ODEProblem(osys, u0map, tspan, parammap; check_length = false,
build_initializeprob = false, kwargs...)
else
Expand Down Expand Up @@ -685,3 +685,5 @@ function (ratemap::JumpSysMajParamMapper{U, V, W})(maj::MassActionJump, newparam
scale_rates && JumpProcesses.scalerates!(maj.scaled_rates, maj.reactant_stoch)
nothing
end

supports_initialization(::JumpSystem) = false
Loading
Loading