# Simple Algebra in MTK

**URL:** <https://discourse.julialang.org/t/simple-algebra-in-mtk/117327>\
**Category:** Modelling & Simulations\
**Tags:** modelingtoolkit\
**Created:** [July 22, 2024, 7:58am UTC](https://discourse.julialang.org/t/simple-algebra-in-mtk/117327 "2024-07-22T07:58:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [July 22, 2024, 7:58am UTC](https://discourse.julialang.org/t/simple-algebra-in-mtk/117327/1 "2024-07-22T07:58:09Z")

</div>

Another beginner question… To what extent can I solve equations in MTK?

```julia
using ModelingToolKit

@mtkmodel Scratch begin
    @variables begin
		x(t)
		y(t)
    end
    @equations begin
		x ~ 3y + 10
		y ~ 2x - 5
    end
end

@mtkbuild fols = Scratch()

probs = ODEProblem(fols, [], (0.0, 10.0), []);

```

yields `MethodError: no method matching AbstractFloat(::Type{SymbolicUtils.BasicSymbolic{Real}})`. Symbolics provides `solve_for`: [Expression Manipulation · Symbolics.jl (juliasymbolics.org)](https://symbolics.juliasymbolics.org/stable/manual/expression_manipulation/#Symbolics.solve_for). Should I give up on `@mtkmodel` and write my equations using Symbolics.jl if I want to be able to call `solve_for`?

`structural_simplify` gives me `The system is unbalanced. There are 2 highest order derivative variables and 1 equations.`, as it seemingly moved one of the equations into the `observed`.

How do people deal with these restrictions? Just accept that some of the algebra will be done by hand? I’d appreciate general wisdom, as MTK is rather intimidating at the moment…

Related: [Using Modeling Toolkit to solve simple equation - Specific Domains / Modelling & Simulations - Julia Programming Language (julialang.org)](https://discourse.julialang.org/t/using-modeling-toolkit-to-solve-simple-equation/114289)

---

<div class="post-metadata">

**Author:** ![YingboMa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yingboma/32/2181_2.png) [@YingboMa](https://discourse.julialang.org/u/YingboMa)\
**Post date:** [July 22, 2024, 1:38pm UTC](https://discourse.julialang.org/t/simple-algebra-in-mtk/117327/2 "2024-07-22T13:38:48Z")

</div>

JuliaSimCompiler fully simplifies the system:

```julia
julia> structural_simplify(IRSystem(fols))
States (0):

Variables (2):
 1 => y
 2 => x
Matched SystemStructure with 2 equations and 2 variables
 # ∂ₜ eq # ∂ₜ v
 1 [(1), 2] | 1 [(1), 2]
 2 [1, 2] | 2 [1, 2]

Legend: Solvable | (Solvable + Matched) | Unsolvable | (Unsolvable + Matched) | ∫ SelectedState

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [July 22, 2024, 1:40pm UTC](https://discourse.julialang.org/t/simple-algebra-in-mtk/117327/3 "2024-07-22T13:40:35Z")

</div>

You have to call simplification for something to happen here, but ModelingToolkit by default will not solve linear equations. However, JuliaSimCompiler will do this

```julia
using ModelingToolKit

@mtkmodel Scratch begin
    @variables begin
		x(t)
		y(t)
    end
    @equations begin
		x ~ 3y + 10
		y ~ 2x - 5
    end
end

@named fols = Scratch()
fols = complete(fols)
ssys = structural_simplify(IRSystem(fols))

probs = ODEProblem(ssys, [], (0.0, 10.0), []);
sol = solve(probs, Tsit5())

```

```julia
julia> sol = solve(probs, Tsit5())
retcode: Success

julia> sol[[fols.x, fols.y]]
9-element Vector{Vector{Float64}}:
 [0.9999999999999999, -3.0]

```

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [July 22, 2024, 2:56pm UTC](https://discourse.julialang.org/t/simple-algebra-in-mtk/117327/4 "2024-07-22T14:56:53Z")

</div>

Your equations are not differential equations, but rather (linear) algebraic equations. So it looks strange to try to pose them as an `ODEProblem`.

An alternative approach:

```julia
using ModelingToolkit, NonlinearSolve

vars = @variables x y

# Define an algebraic system
eqs = [x ~ 3y + 10
        y ~ 2x - 5]
@mtkbuild sys = NonlinearSystem(eqs, vars, [])

```

OK – this doesn’t solve the equation symbolically, but you can proceed similarly as to for differential equations and create a `NonlinearProblem` and solve it. [There is also a `LinearSolve.jl`]

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [July 29, 2024, 5:52am UTC](https://discourse.julialang.org/t/simple-algebra-in-mtk/117327/5 "2024-07-29T05:52:39Z")

</div>

If I’m reading correctly, I could drop `@mtkmodel`, write the equations with Symbolics, and call [solve\_for](https://docs.sciml.ai/Symbolics/stable/manual/expression_manipulation/#Symbolics.solve_for) manually. Apparently it’s limited to linear equations. Is JuliaSimCompiler able to solve more complicated systems?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [July 29, 2024, 7:16am UTC](https://discourse.julialang.org/t/simple-algebra-in-mtk/117327/6 "2024-07-29T07:16:10Z")

</div>

> [@cstjean](#):
>
> Is JuliaSimCompiler able to solve more complicated systems?

MTK solves no systems at all, while JSCompiler currently solves linear systems. For JSCompiler to solve nonlinear systems inline is on the horizon.

When I say _solve_ here, I mean that JSCompiler recognizes patterns like Ax = b in the dynamics and emits code for `x = A\b`, avoding the introduction of algebraic equations. MTK would treat this as a DAE system instead.
