diff --git a/README.md b/README.md index 2073663147..0fcd128f7a 100644 --- a/README.md +++ b/README.md @@ -21,16 +21,16 @@ to manipulate. ### Example: ODE Let's build an ODE. First we define some variables. In a differential equation -system, we need to differentiate between our unknown (dependent) variables +system, we need to differentiate between our (dependent) variables and parameters. Therefore we label them as follows: ```julia using ModelingToolkit # Define some variables -@Param t σ ρ β -@Unknown x(t) y(t) z(t) -@Deriv D'~t +@parameters t σ ρ β +@variables x(t) y(t) z(t) +@derivatives D'~t ``` Then we build the system: @@ -78,11 +78,11 @@ f = ODEFunction(de) We can also build nonlinear systems. Let's say we wanted to solve for the steady state of the previous ODE. This is the nonlinear system defined by where the -derivatives are zero. We use unknown variables for our nonlinear system. +derivatives are zero. We use (unknown) variables for our nonlinear system. ```julia -@Unknown x y z -@Param σ ρ β +@variables x y z +@parameters σ ρ β # Define a nonlinear system eqs = [0 ~ σ*(y-x), @@ -173,7 +173,7 @@ structure is as follows: the system of equations. - Name to subtype mappings: these describe how variable `subtype`s are mapped to the contexts of the system. For example, for a differential equation, - the unknown variable corresponds to given subtypes and then the `eqs` can + the variable corresponds to given subtypes and then the `eqs` can be analyzed knowing what the state variables are. - Variable names which do not fall into one of the system's core subtypes are treated as intermediates which can be used for holding subcalculations and @@ -223,7 +223,7 @@ function via the dispatch: ```julia # `N` arguments are accepted by the relevant method of `my_function` -ModelingToolkit.Derivative(::typeof(my_function), args::NTuple{N,Any}, ::Val{i}) +ModelingToolkit.derivative(::typeof(my_function), args::NTuple{N,Any}, ::Val{i}) ``` where `i` means that it's the derivative of the `i`th argument. `args` is the @@ -233,7 +233,7 @@ You should return an `Operation` for the derivative of your function. For example, `sin(t)`'s derivative (by `t`) is given by the following: ```julia -ModelingToolkit.Derivative(::typeof(sin), args::NTuple{1,Any}, ::Val{1}) = cos(args[1]) +ModelingToolkit.derivative(::typeof(sin), args::NTuple{1,Any}, ::Val{1}) = cos(args[1]) ``` ### Macro-free Usage @@ -243,22 +243,22 @@ is accessible via a function-based interface. This means that all macros are syntactic sugar in some form. For example, the variable construction: ```julia -@Param t σ ρ β -@Unknown x(t) y(t) z(t) -@Deriv D'~t +@parameters t σ ρ β +@variables x(t) y(t) z(t) +@derivatives D'~t ``` is syntactic sugar for: ```julia -t = Parameter(:t) -x = Unknown(:x, [t]) -y = Unknown(:y, [t]) -z = Unknown(:z, [t]) +t = Variable(:t; known = true) +x = Variable(:x, [t]) +y = Variable(:y, [t]) +z = Variable(:z, [t]) D = Differential(t) -σ = Parameter(:σ) -ρ = Parameter(:ρ) -β = Parameter(:β) +σ = Variable(:σ; known = true) +ρ = Variable(:ρ; known = true) +β = Variable(:β; known = true) ``` ### Intermediate Calculations @@ -266,8 +266,8 @@ D = Differential(t) The system building functions can handle intermediate calculations. For example, ```julia -@Unknown x y z -@Param σ ρ β +@variables x y z +@parameters σ ρ β a = y - x eqs = [0 ~ σ*a, 0 ~ x*(ρ-z)-y, diff --git a/src/ModelingToolkit.jl b/src/ModelingToolkit.jl index 56693a3441..5ad35ad2ce 100644 --- a/src/ModelingToolkit.jl +++ b/src/ModelingToolkit.jl @@ -1,5 +1,10 @@ module ModelingToolkit +export Operation, Expression +export calculate_jacobian, generate_jacobian, generate_function +export @register + + using DiffEqBase using StaticArrays, LinearAlgebra @@ -30,9 +35,4 @@ include("function_registration.jl") include("simplify.jl") include("utils.jl") -export Operation, Expression, AbstractComponent -export calculate_jacobian, generate_jacobian, generate_function -export ArrayFunction, SArrayFunction -export @register - end # module diff --git a/src/differentials.jl b/src/differentials.jl index 08bd80de3d..25a0498e76 100644 --- a/src/differentials.jl +++ b/src/differentials.jl @@ -1,3 +1,6 @@ +export Differential, expand_derivatives, @derivatives + + struct Differential <: Function x::Expression end @@ -12,7 +15,7 @@ function (D::Differential)(x::Variable) return Operation(D, Expression[x]) end (::Differential)(::Any) = Constant(0) -Base.:(==)(D1::Differential, D2::Differential) = D1.x == D2.x +Base.:(==)(D1::Differential, D2::Differential) = isequal(D1.x, D2.x) function expand_derivatives(O::Operation) @. O.args = expand_derivatives(O.args) @@ -21,7 +24,7 @@ function expand_derivatives(O::Operation) D = O.op o = O.args[1] isa(o, Operation) || return O - return simplify_constants(sum(i->Derivative(o,i)*expand_derivatives(D(o.args[i])),1:length(o.args))) + return simplify_constants(sum(i->derivative(o,i)*expand_derivatives(D(o.args[i])),1:length(o.args))) end return O @@ -29,13 +32,13 @@ end expand_derivatives(x) = x # Don't specialize on the function here -Derivative(O::Operation, idx) = Derivative(O.op, (O.args...,), Val(idx)) +derivative(O::Operation, idx) = derivative(O.op, (O.args...,), Val(idx)) # Pre-defined derivatives import DiffRules, SpecialFunctions, NaNMath for (modu, fun, arity) ∈ DiffRules.diffrules() for i ∈ 1:arity - @eval function Derivative(::typeof($modu.$fun), args::NTuple{$arity,Any}, ::Val{$i}) + @eval function derivative(::typeof($modu.$fun), args::NTuple{$arity,Any}, ::Val{$i}) M, f = $(modu, fun) partials = DiffRules.diffrule(M, f, args...) dx = @static $arity == 1 ? partials : partials[$i] @@ -60,7 +63,7 @@ function _differential_macro(x) lhss = Symbol[] x = flatten_expr!(x) for di in x - @assert di isa Expr && di.args[1] == :~ "@Deriv expects a form that looks like `@Deriv D''~t E'~t`" + @assert di isa Expr && di.args[1] == :~ "@derivatives expects a form that looks like `@derivatives D''~t E'~t`" lhs = di.args[2] rhs = di.args[3] order, lhs = count_order(lhs) @@ -72,12 +75,10 @@ function _differential_macro(x) ex end -macro Deriv(x...) +macro derivatives(x...) esc(_differential_macro(x)) end function calculate_jacobian(eqs,vars) Expression[Differential(vars[j])(eqs[i]) for i in 1:length(eqs), j in 1:length(vars)] end - -export Differential, expand_derivatives, @Deriv, calculate_jacobian diff --git a/src/equations.jl b/src/equations.jl index e721eb70f9..a914b81142 100644 --- a/src/equations.jl +++ b/src/equations.jl @@ -5,7 +5,7 @@ struct Equation lhs::Expression rhs::Expression end -Base.:(==)(a::Equation, b::Equation) = (a.lhs, a.rhs) == (b.lhs, b.rhs) +Base.:(==)(a::Equation, b::Equation) = isequal((a.lhs, a.rhs), (b.lhs, b.rhs)) Base.:~(lhs::Expression, rhs::Expression) = Equation(lhs, rhs) Base.:~(lhs::Expression, rhs::Number ) = Equation(lhs, rhs) @@ -13,7 +13,7 @@ Base.:~(lhs::Number , rhs::Expression) = Equation(lhs, rhs) _is_dependent(x::Variable) = !x.known && !isempty(x.dependents) -_is_parameter(iv) = x -> x.known && x ≠ iv +_is_parameter(iv) = x -> x.known && !isequal(x, iv) _is_known(x::Variable) = x.known _is_unknown(x::Variable) = !x.known diff --git a/src/function_registration.jl b/src/function_registration.jl index cc72ba685f..61a2e8a15a 100644 --- a/src/function_registration.jl +++ b/src/function_registration.jl @@ -32,7 +32,13 @@ for (M, f, arity) in DiffRules.diffrules() @eval @register $sig end -for fun = (:<, :>, :(==), :!, :&, :|, :div) +for fun ∈ [:!] + basefun = Expr(:., Base, QuoteNode(fun)) + sig = :($basefun(x)) + @eval @register $sig +end + +for fun ∈ [:<, :>, :(==), :&, :|, :div] basefun = Expr(:., Base, QuoteNode(fun)) sig = :($basefun(x,y)) @eval @register $sig diff --git a/src/operations.jl b/src/operations.jl index f024b848e3..03c794f16e 100644 --- a/src/operations.jl +++ b/src/operations.jl @@ -4,15 +4,15 @@ struct Operation <: Expression end # Recursive == -function Base.:(==)(x::Operation,y::Operation) +function Base.isequal(x::Operation,y::Operation) x.op == y.op && length(x.args) == length(y.args) && all(isequal.(x.args,y.args)) end -Base.:(==)(::Operation, ::Number ) = false -Base.:(==)(::Number , ::Operation) = false -Base.:(==)(::Operation, ::Variable ) = false -Base.:(==)(::Variable , ::Operation) = false -Base.:(==)(::Operation, ::Constant ) = false -Base.:(==)(::Constant , ::Operation) = false +Base.isequal(::Operation, ::Number ) = false +Base.isequal(::Number , ::Operation) = false +Base.isequal(::Operation, ::Variable ) = false +Base.isequal(::Variable , ::Operation) = false +Base.isequal(::Operation, ::Constant ) = false +Base.isequal(::Constant , ::Operation) = false Base.convert(::Type{Expr}, O::Operation) = build_expr(:call, Any[Symbol(O.op); convert.(Expr, O.args)]) diff --git a/src/simplify.jl b/src/simplify.jl index 0c897face3..53206f0688 100644 --- a/src/simplify.jl +++ b/src/simplify.jl @@ -1,10 +1,13 @@ +export simplify_constants + + function simplify_constants(O::Operation, shorten_tree) while true O′ = _simplify_constants(O, shorten_tree) if is_operation(O′) O′ = Operation(O′.op, simplify_constants.(O′.args, shorten_tree)) end - O == O′ && return O + isequal(O, O′) && return O O = O′ end end @@ -72,5 +75,3 @@ function _simplify_constants(O::Operation, shorten_tree) end _simplify_constants(x, shorten_tree) = x _simplify_constants(x) = _simplify_constants(x, true) - -export simplify_constants diff --git a/src/systems/diffeqs/diffeqsystem.jl b/src/systems/diffeqs/diffeqsystem.jl index ad1e35393c..24204c4832 100644 --- a/src/systems/diffeqs/diffeqsystem.jl +++ b/src/systems/diffeqs/diffeqsystem.jl @@ -10,7 +10,7 @@ function flatten_differential(O::Operation) @assert is_derivative(O) "invalid differential: $O" is_derivative(O.args[1]) || return (O.args[1], O.op.x, 1) (x, t, order) = flatten_differential(O.args[1]) - t == O.op.x || throw(ArgumentError("non-matching differentials on lhs: $t, $(O.op.x)")) + isequal(t, O.op.x) || throw(ArgumentError("non-matching differentials on lhs: $t, $(O.op.x)")) return (x, t, order + 1) end @@ -26,7 +26,7 @@ function Base.convert(::Type{DiffEq}, eq::Equation) (x, t, n) = flatten_differential(eq.lhs) return DiffEq(x, t, n, eq.rhs) end -Base.:(==)(a::DiffEq, b::DiffEq) = (a.x, a.t, a.n, a.rhs) == (b.x, b.t, b.n, b.rhs) +Base.:(==)(a::DiffEq, b::DiffEq) = isequal((a.x, a.t, a.n, a.rhs), (b.x, b.t, b.n, b.rhs)) get_args(eq::DiffEq) = Expression[eq.x, eq.t, eq.rhs] struct DiffEqSystem <: AbstractSystem @@ -79,7 +79,7 @@ end function generate_ode_iW(sys::DiffEqSystem, simplify=true; version::FunctionVersion = ArrayFunction) jac = calculate_jacobian(sys) - gam = Parameter(:gam) + gam = Variable(:gam; known = true) W = LinearAlgebra.I - gam*jac W = SMatrix{size(W,1),size(W,2)}(W) diff --git a/src/systems/diffeqs/first_order_transform.jl b/src/systems/diffeqs/first_order_transform.jl index 706de49f9a..c0db1574cf 100644 --- a/src/systems/diffeqs/first_order_transform.jl +++ b/src/systems/diffeqs/first_order_transform.jl @@ -1,7 +1,10 @@ +export ode_order_lowering + + function lower_varname(var::Variable, idv, order) order == 0 && return var name = Symbol(var.name, :_, string(idv.name)^order) - return Variable(name, var.known, var.dependents) + return Variable(name, var.dependents; known = var.known) end function ode_order_lowering(sys::DiffEqSystem) @@ -17,7 +20,7 @@ function ode_order_lowering(eqs, iv) var, maxorder = eq.x, eq.n if maxorder > get(var_order, var, 0) var_order[var] = maxorder - var ∈ vars || push!(vars, var) + any(isequal(var), vars) || push!(vars, var) end var′ = lower_varname(eq.x, eq.t, eq.n - 1) rhs′ = rename(eq.rhs) @@ -45,5 +48,3 @@ function rename(O::Expression) end return Operation(O.op, rename.(O.args)) end - -export ode_order_lowering diff --git a/src/utils.jl b/src/utils.jl index f5e83aeae3..e8753f7500 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -65,4 +65,4 @@ is_derivative(::Any) = false has_dependent(t::Variable) = Base.Fix2(has_dependent, t) has_dependent(x::Variable, t::Variable) = - t ∈ x.dependents || any(has_dependent(t), x.dependents) + any(isequal(t), x.dependents) || any(has_dependent(t), x.dependents) diff --git a/src/variables.jl b/src/variables.jl index 32f4a9ff79..4777eed673 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -1,15 +1,14 @@ -export Variable, Unknown, Parameter, @Unknown, @Param +export Variable, @variables, @parameters struct Variable <: Expression name::Symbol - known::Bool dependents::Vector{Variable} + known::Bool + Variable(name, dependents = Variable[]; known = false) = + new(name, dependents, known) end -Parameter(name, dependents = Variable[]) = Variable(name, true, dependents) -Unknown(name, dependents = Variable[]) = Variable(name, false, dependents) - struct Constant <: Expression value::Number @@ -22,14 +21,14 @@ Base.isone(ex::Expression) = isa(ex, Constant) && isone(ex.value) # Variables use isequal for equality since == is an Operation -Base.:(==)(x::Variable, y::Variable) = (x.name, x.known) == (y.name, y.known) -Base.:(==)(::Variable, ::Number) = false -Base.:(==)(::Number, ::Variable) = false -Base.:(==)(::Variable, ::Constant) = false -Base.:(==)(::Constant, ::Variable) = false -Base.:(==)(c::Constant, n::Number) = c.value == n -Base.:(==)(n::Number, c::Constant) = c.value == n -Base.:(==)(a::Constant, b::Constant) = a.value == b.value +Base.isequal(x::Variable, y::Variable) = (x.name, x.known) == (y.name, y.known) +Base.isequal(::Variable, ::Number) = false +Base.isequal(::Number, ::Variable) = false +Base.isequal(::Variable, ::Constant) = false +Base.isequal(::Constant, ::Variable) = false +Base.isequal(c::Constant, n::Number) = c.value == n +Base.isequal(n::Number, c::Constant) = c.value == n +Base.isequal(a::Constant, b::Constant) = a.value == b.value function Base.convert(::Type{Expr}, x::Variable) x.known || return x.name @@ -41,7 +40,7 @@ Base.convert(::Type{Expr}, c::Constant) = c.value Base.show(io::IO, x::Variable) = print(io, x.name) # Build variables more easily -function _parse_vars(macroname, fun, x) +function _parse_vars(macroname, known, x) ex = Expr(:block) var_names = Symbol[] # if parsing things in the form of @@ -65,15 +64,15 @@ function _parse_vars(macroname, fun, x) end push!(var_names, var_name) - expr = :($var_name = $fun($(Meta.quot(var_name)), $dependents)) + expr = :($var_name = $Variable($(Meta.quot(var_name)), $dependents; known = $known)) push!(ex.args, expr) end push!(ex.args, build_expr(:tuple, var_names)) return ex end -macro Unknown(xs...) - esc(_parse_vars(:Unknown, Unknown, xs)) +macro variables(xs...) + esc(_parse_vars(:Variable, false, xs)) end -macro Param(xs...) - esc(_parse_vars(:Param, Parameter, xs)) +macro parameters(xs...) + esc(_parse_vars(:Param, true, xs)) end diff --git a/test/derivatives.jl b/test/derivatives.jl index 768fd80b14..999cad9a70 100644 --- a/test/derivatives.jl +++ b/test/derivatives.jl @@ -2,56 +2,56 @@ using ModelingToolkit using Test # Derivatives -@Param t σ ρ β -@Unknown x(t) y(t) z(t) -@Deriv D'~t D2''~t +@parameters t σ ρ β +@variables x(t) y(t) z(t) +@derivatives D'~t D2''~t -@test expand_derivatives(D(t)) == 1 -@test expand_derivatives(D(D(t))) == 0 +@test isequal(expand_derivatives(D(t)), 1) +@test isequal(expand_derivatives(D(D(t))), 0) dsin = D(sin(t)) -@test expand_derivatives(dsin) == cos(t) +@test isequal(expand_derivatives(dsin), cos(t)) dcsch = D(csch(t)) -@test expand_derivatives(dcsch) == simplify_constants(coth(t) * csch(t) * -1) +@test isequal(expand_derivatives(dcsch), simplify_constants(coth(t) * csch(t) * -1)) -@test expand_derivatives(D(-7)) == 0 -@test expand_derivatives(D(sin(2t))) == simplify_constants(cos(2t) * 2) -@test expand_derivatives(D2(sin(t))) == simplify_constants(-sin(t)) -@test expand_derivatives(D2(sin(2t))) == simplify_constants(sin(2t) * -4) -@test expand_derivatives(D2(t)) == 0 -@test expand_derivatives(D2(5)) == 0 +@test isequal(expand_derivatives(D(-7)), 0) +@test isequal(expand_derivatives(D(sin(2t))), simplify_constants(cos(2t) * 2)) +@test isequal(expand_derivatives(D2(sin(t))), simplify_constants(-sin(t))) +@test isequal(expand_derivatives(D2(sin(2t))), simplify_constants(sin(2t) * -4)) +@test isequal(expand_derivatives(D2(t)), 0) +@test isequal(expand_derivatives(D2(5)), 0) # Chain rule dsinsin = D(sin(sin(t))) -@test expand_derivatives(dsinsin) == cos(sin(t))*cos(t) +@test isequal(expand_derivatives(dsinsin), cos(sin(t))*cos(t)) d1 = D(sin(t)*t) d2 = D(sin(t)*cos(t)) -@test expand_derivatives(d1) == t*cos(t)+sin(t) -@test expand_derivatives(d2) == simplify_constants(cos(t)*cos(t)+sin(t)*(-1*sin(t))) +@test isequal(expand_derivatives(d1), t*cos(t)+sin(t)) +@test isequal(expand_derivatives(d2), simplify_constants(cos(t)*cos(t)+sin(t)*(-1*sin(t)))) eqs = [0 ~ σ*(y-x), 0 ~ x*(ρ-z)-y, 0 ~ x*y - β*z] sys = NonlinearSystem(eqs,[x,y,z],[σ,ρ,β]) jac = calculate_jacobian(sys) -@test jac[1,1] == σ*-1 -@test jac[1,2] == σ -@test jac[1,3] == 0 -@test jac[2,1] == ρ-z -@test jac[2,2] == -1 -@test jac[2,3] == x*-1 -@test jac[3,1] == y -@test jac[3,2] == x -@test jac[3,3] == -1*β +@test isequal(jac[1,1], σ*-1) +@test isequal(jac[1,2], σ) +@test isequal(jac[1,3], 0) +@test isequal(jac[2,1], ρ-z) +@test isequal(jac[2,2], -1) +@test isequal(jac[2,3], x*-1) +@test isequal(jac[3,1], y) +@test isequal(jac[3,2], x) +@test isequal(jac[3,3], -1*β) # Variable dependence checking in differentiation -@Unknown a(t) b(a) -@test D(b) ≠ 0 +@variables a(t) b(a) +@test !isequal(D(b), 0) -@test expand_derivatives(D(x * y)) == simplify_constants(y*D(x) + x*D(y)) -@test_broken expand_derivatives(D(x * y)) == simplify_constants(D(x)*y + x*D(y)) +@test isequal(expand_derivatives(D(x * y)), simplify_constants(y*D(x) + x*D(y))) +@test_broken isequal(expand_derivatives(D(x * y)), simplify_constants(D(x)*y + x*D(y))) -@test expand_derivatives(D(2t)) == 2 -@test expand_derivatives(D(2x)) == 2D(x) +@test isequal(expand_derivatives(D(2t)), 2) +@test isequal(expand_derivatives(D(2x)), 2D(x)) diff --git a/test/simplify.jl b/test/simplify.jl index 0e2f876bc5..be6c1554df 100644 --- a/test/simplify.jl +++ b/test/simplify.jl @@ -1,18 +1,18 @@ using ModelingToolkit using Test -@Param t -@Unknown x(t) y(t) z(t) +@parameters t +@variables x(t) y(t) z(t) null_op = 0*t -@test simplify_constants(null_op) == 0 +@test isequal(simplify_constants(null_op), 0) one_op = 1*t -@test simplify_constants(one_op) == t +@test isequal(simplify_constants(one_op), t) identity_op = Operation(identity,[x]) -@test simplify_constants(identity_op) == x +@test isequal(simplify_constants(identity_op), x) minus_op = -x -@test simplify_constants(minus_op) == -1*x +@test isequal(simplify_constants(minus_op), -1*x) simplify_constants(minus_op) diff --git a/test/system_construction.jl b/test/system_construction.jl index 7fa89c2a08..120607e6b6 100644 --- a/test/system_construction.jl +++ b/test/system_construction.jl @@ -2,9 +2,9 @@ using ModelingToolkit using Test # Define some variables -@Param t σ ρ β -@Unknown x(t) y(t) z(t) -@Deriv D'~t +@parameters t σ ρ β +@variables x(t) y(t) z(t) +@derivatives D'~t # Define a differential equation eqs = [D(x) ~ σ*(y-x), @@ -22,7 +22,7 @@ ModelingToolkit.generate_ode_iW(de) de2 = DiffEqSystem(eqs, t) function test_vars_extraction(de, de2) - @test de.iv == de2.iv + @test isequal(de.iv, de2.iv) for el in (:dvs, :ps) names2 = sort(collect(var.name for var in getfield(de2,el))) names = sort(collect(var.name for var in getfield(de,el))) @@ -32,7 +32,7 @@ end test_vars_extraction(de, de2) @testset "time-varying parameters" begin - @Param σ′(t) + @parameters σ′(t) eqs = [D(x) ~ σ′*(y-x), D(y) ~ x*(ρ-z)-y, D(z) ~ x*y - β*z] @@ -46,9 +46,9 @@ test_vars_extraction(de, de2) end # Conversion to first-order ODEs #17 -@Deriv D3'''~t -@Deriv D2''~t -@Unknown u(t) u_tt(t) u_t(t) x_t(t) +@derivatives D3'''~t +@derivatives D2''~t +@variables u(t) u_tt(t) u_t(t) x_t(t) eqs = [D3(u) ~ 2(D2(u)) + D(u) + D(x) + 1 D2(x) ~ D(x) + 2] de = DiffEqSystem(eqs, t) @@ -84,8 +84,8 @@ end generate_function(ns) -@Deriv D'~t -@Param A B C +@derivatives D'~t +@parameters A B C _x = y / C eqs = [D(x) ~ -A*x, D(y) ~ A*x - B*_x] @@ -100,8 +100,8 @@ test_vars_extraction(de, DiffEqSystem(eqs)) end # Now nonlinear system with only variables -@Unknown x y z -@Param σ ρ β +@variables x y z +@parameters σ ρ β # Define a nonlinear system eqs = [0 ~ σ*(y-x), @@ -110,15 +110,15 @@ eqs = [0 ~ σ*(y-x), ns = NonlinearSystem(eqs, [x,y,z], [σ,ρ,β]) jac = calculate_jacobian(ns) @testset "nlsys jacobian" begin - @test jac[1,1] == σ * -1 - @test jac[1,2] == σ - @test jac[1,3] == 0 - @test jac[2,1] == ρ - z - @test jac[2,2] == -1 - @test jac[2,3] == x * -1 - @test jac[3,1] == y - @test jac[3,2] == x - @test jac[3,3] == -1 * β + @test isequal(jac[1,1], σ * -1) + @test isequal(jac[1,2], σ) + @test isequal(jac[1,3], 0) + @test isequal(jac[2,1], ρ - z) + @test isequal(jac[2,2], -1) + @test isequal(jac[2,3], x * -1) + @test isequal(jac[3,1], y) + @test isequal(jac[3,2], x) + @test isequal(jac[3,3], -1 * β) end nlsys_func = generate_function(ns) jac_func = generate_jacobian(ns) diff --git a/test/variable_parsing.jl b/test/variable_parsing.jl index 96ba18aecd..759652f110 100644 --- a/test/variable_parsing.jl +++ b/test/variable_parsing.jl @@ -1,33 +1,35 @@ using ModelingToolkit using Test -@Param t -@Unknown x(t) -@Unknown y(t) -@Unknown z(t) -x1 = Unknown(:x, [t]) -y1 = Unknown(:y, [t]) -z1 = Unknown(:z, [t]) -@test x1 == x -@test y1 == y -@test z1 == z +@parameters t +@variables x(t) +@variables y(t) +@variables z(t) +x1 = Variable(:x, [t]) +y1 = Variable(:y, [t]) +z1 = Variable(:z, [t]) +@test isequal(x1, x) +@test isequal(y1, y) +@test isequal(z1, z) @test convert(Expr, x) == :x @test convert(Expr, y) == :y @test convert(Expr, z) == :z -@Param begin +@parameters begin t s end -t1 = Parameter(:t) -s1 = Parameter(:s) -@test t1 == t -@test s1 == s +t1 = Variable(:t; known = true) +s1 = Variable(:s; known = true) +@test isequal(t1, t) +@test isequal(s1, s) @test convert(Expr, t) == :t @test convert(Expr, s) == :s @test convert(Expr, cos(t + sin(s))) == :(cos(t + sin(s))) -@Deriv D'~t +@derivatives D'~t D1 = Differential(t) @test D1 == D @test convert(Expr, D) == D + +@test isequal(x ≤ y + 1, (x < y + 1) | (x == y + 1))