1
1
using OrdinaryDiffEq, ModelingToolkit, DataStructures, Test
2
2
using Optimization, RecursiveArrayTools, OptimizationOptimJL
3
+ using LabelledArrays, SymbolicIndexingInterface
4
+ using ModelingToolkit: t_nounits as t, D_nounits as D
5
+ using SciMLBase: parameterless_type
3
6
4
7
N = 32
5
8
const 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)
252
255
problem = ODEProblem (SIR!, u0, tspan, p)
253
256
sys = complete (modelingtoolkitize (problem))
254
257
255
- @parameters t
256
258
@test all (isequal .(parameters (sys), getproperty .(@variables (β, η, ω, φ, σ, μ), :val )))
257
259
@test all (isequal .(Symbol .(unknowns (sys)), Symbol .(@variables (S (t), I (t), R (t), C (t)))))
258
260
@@ -291,9 +293,8 @@ sys = modelingtoolkitize(prob)
291
293
@test [ModelingToolkit. defaults (sys)[s] for s in parameters (sys)] == [10 , 20 ]
292
294
@test ModelingToolkit. has_tspan (sys)
293
295
294
- @parameters t sig= 10 rho= 28.0 beta= 8 / 3
296
+ @parameters sig= 10 rho= 28.0 beta= 8 / 3
295
297
@variables x (t)= 100 y (t)= 1.0 z (t)= 1
296
- D = Differential (t)
297
298
298
299
eqs = [D (x) ~ sig * (y - x),
299
300
D (y) ~ x * (rho - z) - y,
@@ -307,3 +308,168 @@ noiseeqs = [0.1 * x,
307
308
prob = SDEProblem (complete (sys))
308
309
sys = modelingtoolkitize (prob)
309
310
@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