11using OrdinaryDiffEq, ModelingToolkit, DataStructures, Test
22using Optimization, RecursiveArrayTools, OptimizationOptimJL
3+ using LabelledArrays, SymbolicIndexingInterface
4+ using ModelingToolkit: t_nounits as t, D_nounits as D
5+ using SciMLBase: parameterless_type
36
47N = 32
58const xyd_brusselator = range (0 , stop = 1 , length = N)
@@ -252,7 +255,6 @@ u0 = @LArray [9998.0, 1.0, 1.0, 1.0] (:S, :I, :R, :C)
252255problem = ODEProblem (SIR!, u0, tspan, p)
253256sys = complete (modelingtoolkitize (problem))
254257
255- @parameters t
256258@test all (isequal .(parameters (sys), getproperty .(@variables (β, η, ω, φ, σ, μ), :val )))
257259@test all (isequal .(Symbol .(unknowns (sys)), Symbol .(@variables (S (t), I (t), R (t), C (t)))))
258260
@@ -291,9 +293,8 @@ sys = modelingtoolkitize(prob)
291293@test [ModelingToolkit. defaults (sys)[s] for s in parameters (sys)] == [10 , 20 ]
292294@test ModelingToolkit. has_tspan (sys)
293295
294- @parameters t sig= 10 rho= 28.0 beta= 8 / 3
296+ @parameters sig= 10 rho= 28.0 beta= 8 / 3
295297@variables x (t)= 100 y (t)= 1.0 z (t)= 1
296- D = Differential (t)
297298
298299eqs = [D (x) ~ sig * (y - x),
299300 D (y) ~ x * (rho - z) - y,
@@ -307,3 +308,168 @@ noiseeqs = [0.1 * x,
307308prob = SDEProblem (complete (sys))
308309sys = modelingtoolkitize (prob)
309310@test ModelingToolkit. has_tspan (sys)
311+
312+ @testset " Explicit variable names" begin
313+ function fn (du, u, p:: NamedTuple , t)
314+ du[1 ] = u[1 ] + p. a * u[2 ]
315+ du[2 ] = u[2 ] + p. b * u[1 ]
316+ end
317+ function fn (du, u, p:: AbstractDict , t)
318+ du[1 ] = u[1 ] + p[:a ] * u[2 ]
319+ du[2 ] = u[2 ] + p[:b ] * u[1 ]
320+ end
321+ function fn (du, u, p, t)
322+ du[1 ] = u[1 ] + p[1 ] * u[2 ]
323+ du[2 ] = u[2 ] + p[2 ] * u[1 ]
324+ end
325+ function fn (du, u, p:: Real , t)
326+ du[1 ] = u[1 ] + p * u[2 ]
327+ du[2 ] = u[2 ] + p * u[1 ]
328+ end
329+ function nl_fn (u, p:: NamedTuple )
330+ [u[1 ] + p. a * u[2 ], u[2 ] + p. b * u[1 ]]
331+ end
332+ function nl_fn (u, p:: AbstractDict )
333+ [u[1 ] + p[:a ] * u[2 ], u[2 ] + p[:b ] * u[1 ]]
334+ end
335+ function nl_fn (u, p)
336+ [u[1 ] + p[1 ] * u[2 ], u[2 ] + p[2 ] * u[1 ]]
337+ end
338+ function nl_fn (u, p:: Real )
339+ [u[1 ] + p * u[2 ], u[2 ] + p * u[1 ]]
340+ end
341+ params = (a = 1 , b = 1 )
342+ odeprob = ODEProblem (fn, [1 1 ], (0 , 1 ), params)
343+ nlprob = NonlinearProblem (nl_fn, [1 , 1 ], params)
344+ optprob = OptimizationProblem (nl_fn, [1 , 1 ], params)
345+
346+ @testset " $(parameterless_type (prob)) " for prob in [optprob]
347+ sys = modelingtoolkitize (prob, u_names = [:a , :b ])
348+ @test is_variable (sys, sys. a)
349+ @test is_variable (sys, sys. b)
350+ @test is_variable (sys, :a )
351+ @test is_variable (sys, :b )
352+
353+ @test_throws [" unknowns" , " 2" , " does not match" , " names" , " 3" ] modelingtoolkitize (
354+ prob, u_names = [:a , :b , :c ])
355+ for (pvals, pnames) in [
356+ ([1 , 2 ], [:p , :q ]),
357+ ((1 , 2 ), [:p , :q ]),
358+ ([1 , 2 ], Dict (1 => :p , 2 => :q )),
359+ ((1 , 2 ), Dict (1 => :p , 2 => :q )),
360+ (1.0 , :p ),
361+ (1.0 , [:p ]),
362+ (1.0 , Dict (1 => :p )),
363+ (Dict (:a => 2 , :b => 4 ), Dict (:a => :p , :b => :q )),
364+ (LVector (a = 1 , b = 2 ), [:p , :q ]),
365+ (SLVector (a = 1 , b = 2 ), [:p , :q ]),
366+ (LVector (a = 1 , b = 2 ), Dict (1 => :p , 2 => :q )),
367+ (SLVector (a = 1 , b = 2 ), Dict (1 => :p , 2 => :q )),
368+ ((a = 1 , b = 2 ), (a = :p , b = :q )),
369+ ((a = 1 , b = 2 ), Dict (:a => :p , :b => :q ))
370+ ]
371+ if pvals isa NamedTuple && prob isa OptimizationProblem
372+ continue
373+ end
374+ sys = modelingtoolkitize (
375+ remake (prob, p = pvals, interpret_symbolicmap = false ), p_names = pnames)
376+ if pnames isa Symbol
377+ @test is_parameter (sys, pnames)
378+ continue
379+ end
380+ for p in values (pnames)
381+ @test is_parameter (sys, p)
382+ end
383+ end
384+
385+ for (pvals, pnames) in [
386+ ([1 , 2 ], [:p , :q , :r ]),
387+ ((1 , 2 ), [:p , :q , :r ]),
388+ ([1 , 2 ], Dict (1 => :p , 2 => :q , 3 => :r )),
389+ ((1 , 2 ), Dict (1 => :p , 2 => :q , 3 => :r )),
390+ (1.0 , [:p , :q ]),
391+ (1.0 , Dict (1 => :p , 2 => :q )),
392+ (Dict (:a => 2 , :b => 4 ), Dict (:a => :p , :b => :q , :c => :r )),
393+ (LVector (a = 1 , b = 2 ), [:p , :q , :r ]),
394+ (SLVector (a = 1 , b = 2 ), [:p , :q , :r ]),
395+ (LVector (a = 1 , b = 2 ), Dict (1 => :p , 2 => :q , 3 => :r )),
396+ (SLVector (a = 1 , b = 2 ), Dict (1 => :p , 2 => :q , 3 => :r )),
397+ ((a = 1 , b = 2 ), (a = :p , b = :q , c = :r )),
398+ ((a = 1 , b = 2 ), Dict (:a => :p , :b => :q , :c => :r ))
399+ ]
400+ newprob = remake (prob, p = pvals, interpret_symbolicmap = false )
401+ @test_throws [
402+ " parameters" , " $(length (pvals)) " , " does not match" , " $(length (pnames)) " ] modelingtoolkitize (
403+ newprob, p_names = pnames)
404+ end
405+
406+ sc = SymbolCache ([:a , :b ], [:p , :q ])
407+ sci_f = parameterless_type (prob. f)(prob. f. f, sys = sc)
408+ newprob = remake (prob, f = sci_f, p = [1 , 2 ])
409+ sys = modelingtoolkitize (newprob)
410+ @test is_variable (sys, sys. a)
411+ @test is_variable (sys, sys. b)
412+ @test is_variable (sys, :a )
413+ @test is_variable (sys, :b )
414+ @test is_parameter (sys, sys. p)
415+ @test is_parameter (sys, sys. q)
416+ @test is_parameter (sys, :p )
417+ @test is_parameter (sys, :q )
418+ end
419+
420+ @testset " From MTK model" begin
421+ @testset " ODE" begin
422+ @variables x (t)= 1.0 y (t)= 2.0
423+ @parameters p= 3.0 q= 4.0
424+ @mtkbuild sys = ODESystem ([D (x) ~ p * y, D (y) ~ q * x], t)
425+ prob1 = ODEProblem (sys, [], (0.0 , 5.0 ))
426+ newsys = complete (modelingtoolkitize (prob1))
427+ @test is_variable (newsys, newsys. x)
428+ @test is_variable (newsys, newsys. y)
429+ @test is_parameter (newsys, newsys. p)
430+ @test is_parameter (newsys, newsys. q)
431+ prob2 = ODEProblem (newsys, [], (0.0 , 5.0 ))
432+
433+ sol1 = solve (prob1, Tsit5 ())
434+ sol2 = solve (prob2, Tsit5 ())
435+ @test sol1 ≈ sol2
436+ end
437+ @testset " Nonlinear" begin
438+ @variables x= 1.0 y= 2.0
439+ @parameters p= 3.0 q= 4.0
440+ @mtkbuild nlsys = NonlinearSystem ([0 ~ p * y^ 2 + x, 0 ~ x + exp (x) * q])
441+ prob1 = NonlinearProblem (nlsys, [])
442+ newsys = complete (modelingtoolkitize (prob1))
443+ @test is_variable (newsys, newsys. x)
444+ @test is_variable (newsys, newsys. y)
445+ @test is_parameter (newsys, newsys. p)
446+ @test is_parameter (newsys, newsys. q)
447+ prob2 = NonlinearProblem (newsys, [])
448+
449+ sol1 = solve (prob1)
450+ sol2 = solve (prob2)
451+ @test sol1 ≈ sol2
452+ end
453+ @testset " Optimization" begin
454+ @variables begin
455+ x = 1.0 , [bounds = (- 2.0 , 10.0 )]
456+ y = 2.0 , [bounds = (- 1.0 , 10.0 )]
457+ end
458+ @parameters p= 3.0 q= 4.0
459+ loss = (p - x)^ 2 + q * (y - x^ 2 )^ 2
460+ @mtkbuild optsys = OptimizationSystem (loss, [x, y], [p, q])
461+ prob1 = OptimizationProblem (optsys, [], grad = true , hess = true )
462+ newsys = complete (modelingtoolkitize (prob1))
463+ @test is_variable (newsys, newsys. x)
464+ @test is_variable (newsys, newsys. y)
465+ @test is_parameter (newsys, newsys. p)
466+ @test is_parameter (newsys, newsys. q)
467+ prob2 = OptimizationProblem (newsys, [], grad = true , hess = true )
468+
469+ sol1 = solve (prob1, GradientDescent ())
470+ sol2 = solve (prob2, GradientDescent ())
471+
472+ @test sol1 ≈ sol2
473+ end
474+ end
475+ end
0 commit comments