SciML / ModelingToolkit.jl

An acausal modeling framework for automatically parallelized scientific machine learning (SciML) in Julia. A computer algebra system for integrated symbolics for physics-informed machine learning and automated transformations of differential equations
https://mtk.sciml.ai/dev/
Other
1.43k stars 209 forks source link

Feature Request: cosmetics for NonlinearSolve #938

Closed azev77 closed 3 years ago

azev77 commented 3 years ago

Issue 1: Currently we need to write:

using ModelingToolkit, NonlinearSolve
@variables  x, y 
@parameters θ
eqs   = [ 0.0 ~ 2.0x - 15.2, 0.0 ~ x + y - 5.2,]
ns    = NonlinearSystem(eqs, [x, y], [θ,])
guess = [x=>1.0, y=>1.0]
ps    = [ θ=>0.45; ]
prob  = NonlinearProblem(ns,guess,ps)
sol   = solve(prob,NewtonRaphson())
tuple(sol...)

It would be great not to require 0 on the LHS:

eqs   = [ 2.0x ~  15.2, x + y ~  5.2,]

Issue 2: Currently we need to repeat x, y when declaring vars/NonlinearSystem()/guess :

using ModelingToolkit, NonlinearSolve
@variables  x, y 
@parameters θ
eqs   = [ 0.0 ~ 2.0x - 15.2, 0.0 ~ x + y - 5.2,]
ns    = NonlinearSystem(eqs, [x, y], [θ,])
guess = [x=>1.0, y=>1.0]
ps    = [ θ=>0.45; ]
prob  = NonlinearProblem(ns,guess,ps)
sol   = solve(prob,NewtonRaphson())
tuple(sol...)

It would be really great if we had the option not to repeat things:

using ModelingToolkit, NonlinearSolve
var = @variables  x, y 
par = @parameters θ
eqs   = [ 0.0 ~ 2.0x - 15.2, 0.0 ~ x + y - 5.2,]
ns    = NonlinearSystem(eqs, var, par)
guess = [1.0, 1.0]
ps    = [0.45;]
prob  = NonlinearProblem(ns,guess,ps)
sol   = solve(prob,NewtonRaphson())
tuple(sol...)
ChrisRackauckas commented 3 years ago

In the constructor we can just do eqs.lhs - eqs.rhs to move them all over. It's an easy fix for whoever has the time.

YingboMa commented 3 years ago

structural_simplify already solves issue 1. For the second issue, you just need to write var = collect(@variables x y)

azev77 commented 3 years ago

Thanks @YingboMa. ODEs can be written w/o structural_simplify: eqs = [D(y) ~ x*(ρ-z)-y] why not nonlinear equations?

YingboMa commented 3 years ago

Because D(y) ~ x*(ρ-z)-y is already the canonical form for ODEs, just like how 0 ~ a + b is the canonical form for nonlinear equations.

azev77 commented 3 years ago
  1. Even though the canonical form for nonlinear equations is 0 ~ y - f(x), -I think y ~ f(x) is much more convenient to write! -I really hope it becomes possible
  2. I tried it w/ structural_simplify(ns) I get an error
    using ModelingToolkit, NonlinearSolve
    var    = collect(@variables  x, y)
    par    = collect(@parameters θ)
    eqs   = [ 2.0x ~ 15.2, 5.2 ~ x + y,]    #
    ns    = NonlinearSystem(eqs, var, par)
    guess = ones(length(var))
    ps    = [ θ=>0.45; ]
    julia> prob  = NonlinearProblem(structural_simplify(ns),guess,ps) #
    ERROR: ArgumentError: States (0) and initial conditions (2) are of different lengths.
    Stacktrace:
    [1] process_NonlinearProblem(constructor::Type, sys::NonlinearSystem, u0map::Vector{Float64}, parammap::Vector{Pair{Num, Float64}}; version::Nothing, jac::Bool, checkbounds::Bool, sparse::Bool, simplify::Bool, linenumbers::Bool, parallel::Symbolics.SerialForm, eval_expression::Bool, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ ModelingToolkit ~\.julia\packages\ModelingToolkit\7KM6m\src\systems\nonlinear\nonlinearsystem.jl:215
    [2] process_NonlinearProblem
    @ ~\.julia\packages\ModelingToolkit\7KM6m\src\systems\nonlinear\nonlinearsystem.jl:208 [inlined]
    [3] (NonlinearProblem{true, isinplace, P, F, K} where {isinplace, P, F, K})(sys::NonlinearSystem, u0map::Vector{Float64}, parammap::Vector{Pair{Num, Float64}}; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ ModelingToolkit ~\.julia\packages\ModelingToolkit\7KM6m\src\systems\nonlinear\nonlinearsystem.jl:243
    [4] (NonlinearProblem{true, isinplace, P, F, K} where {isinplace, P, F, K})(sys::NonlinearSystem, u0map::Vector{Float64}, parammap::Vector{Pair{Num, Float64}})
    @ ModelingToolkit ~\.julia\packages\ModelingToolkit\7KM6m\src\systems\nonlinear\nonlinearsystem.jl:243
    [5] NonlinearProblem(::NonlinearSystem, ::Vector{Float64}, ::Vararg{Any, N} where N; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ ModelingToolkit ~\.julia\packages\ModelingToolkit\7KM6m\src\systems\nonlinear\nonlinearsystem.jl:225
    [6] NonlinearProblem(::NonlinearSystem, ::Vector{Float64}, ::Vararg{Any, N} where N)
    @ ModelingToolkit ~\.julia\packages\ModelingToolkit\7KM6m\src\systems\nonlinear\nonlinearsystem.jl:225
    [7] top-level scope
    @ REPL[193]:1
YingboMa commented 3 years ago
  1. Still, you just need to write structural_simplify. We don't do constructor-level simplification.
  2. That's because all the states are reduced by structural_simplify https://github.com/SciML/DiffEqBase.jl/issues/650