@@ -494,6 +494,14 @@ function SymbolicIndexingInterface.is_observed(sys::AbstractSystem, sym)
494494 ! is_independent_variable (sys, sym) && symbolic_type (sym) != NotSymbolic ()
495495end
496496
497+ function SymbolicIndexingInterface. observed (sys:: AbstractSystem , sym)
498+ return let _fn = build_explicit_observed_function (sys, sym)
499+ fn (u, p, t) = _fn (u, p, t)
500+ fn (u, p:: MTKParameters , t) = _fn (u, p... , t)
501+ fn
502+ end
503+ end
504+
497505function SymbolicIndexingInterface. default_values (sys:: AbstractSystem )
498506 return merge (
499507 Dict (eq. lhs => eq. rhs for eq in observed (sys)),
@@ -1020,7 +1028,15 @@ function defaults(sys::AbstractSystem)
10201028 isempty (systems) ? defs : mapfoldr (namespace_defaults, merge, systems; init = defs)
10211029end
10221030
1031+ function defaults_and_guesses (sys:: AbstractSystem )
1032+ merge (guesses (sys), defaults (sys))
1033+ end
1034+
10231035unknowns (sys:: Union{AbstractSystem, Nothing} , v) = renamespace (sys, v)
1036+ for vType in [Symbolics. Arr, Symbolics. Symbolic{<: AbstractArray }]
1037+ @eval unknowns (sys:: AbstractSystem , v:: $vType ) = renamespace (sys, v)
1038+ @eval parameters (sys:: AbstractSystem , v:: $vType ) = toparam (unknowns (sys, v))
1039+ end
10241040parameters (sys:: Union{AbstractSystem, Nothing} , v) = toparam (unknowns (sys, v))
10251041for f in [:unknowns , :parameters ]
10261042 @eval function $f (sys:: AbstractSystem , vs:: AbstractArray )
@@ -1756,34 +1772,117 @@ function linearization_function(sys::AbstractSystem, inputs,
17561772 op = merge (defs, op)
17571773 end
17581774 sys = ssys
1759- x0 = merge (defaults (sys), Dict (missing_variable_defaults (sys)), op)
1760- u0, _p, _ = get_u0_p (sys, x0, p; use_union = false , tofloat = true )
1761- ps = parameters (sys)
1775+ initsys = complete (generate_initializesystem (
1776+ sys, guesses = guesses (sys), algebraic_only = true ))
1777+ if p isa SciMLBase. NullParameters
1778+ p = Dict ()
1779+ else
1780+ p = todict (p)
1781+ end
1782+ x0 = merge (defaults_and_guesses (sys), op)
17621783 if has_index_cache (sys) && get_index_cache (sys) != = nothing
1763- p = MTKParameters (sys, p, u0)
1784+ sys_ps = MTKParameters (sys, p, x0)
1785+ else
1786+ sys_ps = varmap_to_vars (p, parameters (sys); defaults = x0)
1787+ end
1788+ p[get_iv (sys)] = NaN
1789+ if has_index_cache (initsys) && get_index_cache (initsys) != = nothing
1790+ oldps = MTKParameters (initsys, p, merge (guesses (sys), defaults (sys), op))
1791+ initsys_ps = parameters (initsys)
1792+ initsys_idxs = [parameter_index (initsys, param) for param in initsys_ps]
1793+ tunable_ps = [initsys_ps[i]
1794+ for i in eachindex (initsys_ps)
1795+ if initsys_idxs[i]. portion == SciMLStructures. Tunable ()]
1796+ tunable_getter = isempty (tunable_ps) ? nothing : getu (sys, tunable_ps)
1797+ discrete_ps = [initsys_ps[i]
1798+ for i in eachindex (initsys_ps)
1799+ if initsys_idxs[i]. portion == SciMLStructures. Discrete ()]
1800+ disc_getter = isempty (discrete_ps) ? nothing : getu (sys, discrete_ps)
1801+ constant_ps = [initsys_ps[i]
1802+ for i in eachindex (initsys_ps)
1803+ if initsys_idxs[i]. portion == SciMLStructures. Constants ()]
1804+ const_getter = isempty (constant_ps) ? nothing : getu (sys, constant_ps)
1805+ nonnum_ps = [initsys_ps[i]
1806+ for i in eachindex (initsys_ps)
1807+ if initsys_idxs[i]. portion == NONNUMERIC_PORTION]
1808+ nonnum_getter = isempty (nonnum_ps) ? nothing : getu (sys, nonnum_ps)
1809+ u_getter = isempty (unknowns (initsys)) ? (_... ) -> nothing :
1810+ getu (sys, unknowns (initsys))
1811+ get_initprob_u_p = let tunable_getter = tunable_getter,
1812+ disc_getter = disc_getter,
1813+ const_getter = const_getter,
1814+ nonnum_getter = nonnum_getter,
1815+ oldps = oldps,
1816+ u_getter = u_getter
1817+
1818+ function (u, p, t)
1819+ state = ProblemState (; u, p, t)
1820+ if tunable_getter != = nothing
1821+ SciMLStructures. replace! (
1822+ SciMLStructures. Tunable (), oldps, tunable_getter (state))
1823+ end
1824+ if disc_getter != = nothing
1825+ SciMLStructures. replace! (
1826+ SciMLStructures. Discrete (), oldps, disc_getter (state))
1827+ end
1828+ if const_getter != = nothing
1829+ SciMLStructures. replace! (
1830+ SciMLStructures. Constants (), oldps, const_getter (state))
1831+ end
1832+ if nonnum_getter != = nothing
1833+ SciMLStructures. replace! (
1834+ NONNUMERIC_PORTION, oldps, nonnum_getter (state))
1835+ end
1836+ newu = u_getter (state)
1837+ return newu, oldps
1838+ end
1839+ end
17641840 else
1765- p = _p
1766- p, split_idxs = split_parameters_by_type (p)
1767- if p isa Tuple
1768- ps = Base. Fix1 (getindex, ps).(split_idxs)
1769- ps = (ps... ,) # if p is Tuple, ps should be Tuple
1841+ get_initprob_u_p = let p_getter = getu (sys, parameters (initsys)),
1842+ u_getter = getu (sys, unknowns (initsys))
1843+
1844+ function (u, p, t)
1845+ state = ProblemState (; u, p, t)
1846+ return u_getter (state), p_getter (state)
1847+ end
17701848 end
17711849 end
1850+ initfn = NonlinearFunction (initsys)
1851+ initprobmap = getu (initsys, unknowns (sys))
1852+ ps = full_parameters (sys)
17721853 lin_fun = let diff_idxs = diff_idxs,
17731854 alge_idxs = alge_idxs,
17741855 input_idxs = input_idxs,
17751856 sts = unknowns (sys),
1776- fun = ODEFunction {true, SciMLBase.FullSpecialize} (sys, unknowns (sys), ps; p = p),
1857+ get_initprob_u_p = get_initprob_u_p,
1858+ fun = ODEFunction {true, SciMLBase.FullSpecialize} (
1859+ sys, unknowns (sys), ps; initializeprobmap = initprobmap),
1860+ initfn = initfn,
17771861 h = build_explicit_observed_function (sys, outputs),
1778- chunk = ForwardDiff. Chunk (input_idxs)
1862+ chunk = ForwardDiff. Chunk (input_idxs),
1863+ sys_ps = sys_ps,
1864+ initialize = initialize,
1865+ sys = sys
17791866
17801867 function (u, p, t)
1868+ if ! isa (p, MTKParameters)
1869+ p = todict (p)
1870+ newps = deepcopy (sys_ps)
1871+ for (k, v) in p
1872+ setp (sys, k)(newps, v)
1873+ end
1874+ p = newps
1875+ end
1876+
17811877 if u != = nothing # Handle systems without unknowns
17821878 length (sts) == length (u) ||
17831879 error (" Number of unknown variables ($(length (sts)) ) does not match the number of input unknowns ($(length (u)) )" )
17841880 if initialize && ! isempty (alge_idxs) # This is expensive and can be omitted if the user knows that the system is already initialized
17851881 residual = fun (u, p, t)
17861882 if norm (residual[alge_idxs]) > √ (eps (eltype (residual)))
1883+ initu0, initp = get_initprob_u_p (u, p, t)
1884+ initprob = NonlinearLeastSquaresProblem (initfn, initu0, initp)
1885+ @set! fun. initializeprob = initprob
17871886 prob = ODEProblem (fun, u, (t, t + 1 ), p)
17881887 integ = init (prob, OrdinaryDiffEq. Rodas5P ())
17891888 u = integ. u
@@ -2051,21 +2150,20 @@ lsys_sym, _ = ModelingToolkit.linearize_symbolic(cl, [f.u], [p.x])
20512150"""
20522151function linearize (sys, lin_fun; t = 0.0 , op = Dict (), allow_input_derivatives = false ,
20532152 p = DiffEqBase. NullParameters ())
2054- x0 = merge (defaults (sys), op)
2055- u0, p2, _ = get_u0_p (sys, x0, p; use_union = false , tofloat = true )
2153+ x0 = merge (defaults (sys), Dict ( missing_variable_defaults (sys)), op)
2154+ u0, defs = get_u0 (sys, x0, p)
20562155 if has_index_cache (sys) && get_index_cache (sys) != = nothing
20572156 if p isa SciMLBase. NullParameters
2058- p = op
2157+ p = Dict ()
20592158 elseif p isa Dict
20602159 p = merge (p, op)
20612160 elseif p isa Vector && eltype (p) <: Pair
20622161 p = merge (Dict (p), op)
20632162 elseif p isa Vector
20642163 p = merge (Dict (parameters (sys) .=> p), op)
20652164 end
2066- p2 = MTKParameters (sys, p, Dict (unknowns (sys) .=> u0))
20672165 end
2068- linres = lin_fun (u0, p2 , t)
2166+ linres = lin_fun (u0, p , t)
20692167 f_x, f_z, g_x, g_z, f_u, g_u, h_x, h_z, h_u = linres
20702168
20712169 nx, nu = size (f_u)
0 commit comments