@@ -494,6 +494,14 @@ function SymbolicIndexingInterface.is_observed(sys::AbstractSystem, sym)
494
494
! is_independent_variable (sys, sym) && symbolic_type (sym) != NotSymbolic ()
495
495
end
496
496
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
+
497
505
function SymbolicIndexingInterface. default_values (sys:: AbstractSystem )
498
506
return merge (
499
507
Dict (eq. lhs => eq. rhs for eq in observed (sys)),
@@ -1020,7 +1028,15 @@ function defaults(sys::AbstractSystem)
1020
1028
isempty (systems) ? defs : mapfoldr (namespace_defaults, merge, systems; init = defs)
1021
1029
end
1022
1030
1031
+ function defaults_and_guesses (sys:: AbstractSystem )
1032
+ merge (guesses (sys), defaults (sys))
1033
+ end
1034
+
1023
1035
unknowns (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
1024
1040
parameters (sys:: Union{AbstractSystem, Nothing} , v) = toparam (unknowns (sys, v))
1025
1041
for f in [:unknowns , :parameters ]
1026
1042
@eval function $f (sys:: AbstractSystem , vs:: AbstractArray )
@@ -1756,34 +1772,117 @@ function linearization_function(sys::AbstractSystem, inputs,
1756
1772
op = merge (defs, op)
1757
1773
end
1758
1774
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)
1762
1783
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
1764
1840
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
1770
1848
end
1771
1849
end
1850
+ initfn = NonlinearFunction (initsys)
1851
+ initprobmap = getu (initsys, unknowns (sys))
1852
+ ps = full_parameters (sys)
1772
1853
lin_fun = let diff_idxs = diff_idxs,
1773
1854
alge_idxs = alge_idxs,
1774
1855
input_idxs = input_idxs,
1775
1856
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,
1777
1861
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
1779
1866
1780
1867
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
+
1781
1877
if u != = nothing # Handle systems without unknowns
1782
1878
length (sts) == length (u) ||
1783
1879
error (" Number of unknown variables ($(length (sts)) ) does not match the number of input unknowns ($(length (u)) )" )
1784
1880
if initialize && ! isempty (alge_idxs) # This is expensive and can be omitted if the user knows that the system is already initialized
1785
1881
residual = fun (u, p, t)
1786
1882
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
1787
1886
prob = ODEProblem (fun, u, (t, t + 1 ), p)
1788
1887
integ = init (prob, OrdinaryDiffEq. Rodas5P ())
1789
1888
u = integ. u
@@ -2051,21 +2150,20 @@ lsys_sym, _ = ModelingToolkit.linearize_symbolic(cl, [f.u], [p.x])
2051
2150
"""
2052
2151
function linearize (sys, lin_fun; t = 0.0 , op = Dict (), allow_input_derivatives = false ,
2053
2152
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)
2056
2155
if has_index_cache (sys) && get_index_cache (sys) != = nothing
2057
2156
if p isa SciMLBase. NullParameters
2058
- p = op
2157
+ p = Dict ()
2059
2158
elseif p isa Dict
2060
2159
p = merge (p, op)
2061
2160
elseif p isa Vector && eltype (p) <: Pair
2062
2161
p = merge (Dict (p), op)
2063
2162
elseif p isa Vector
2064
2163
p = merge (Dict (parameters (sys) .=> p), op)
2065
2164
end
2066
- p2 = MTKParameters (sys, p, Dict (unknowns (sys) .=> u0))
2067
2165
end
2068
- linres = lin_fun (u0, p2 , t)
2166
+ linres = lin_fun (u0, p , t)
2069
2167
f_x, f_z, g_x, g_z, f_u, g_u, h_x, h_z, h_u = linres
2070
2168
2071
2169
nx, nu = size (f_u)
0 commit comments