Skip to content

Commit ae1be16

Browse files
converting to C tutorial
1 parent fecc342 commit ae1be16

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

docs/make.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ makedocs(
1717
"tutorials/nonlinear.md",
1818
"tutorials/modelingtoolkitize.md",
1919
"tutorials/auto_parallel.md"
20+
"tutorials/coverting_to_C.md"
2021
],
2122
"Systems" => Any[
2223
"systems/AbstractSystem.md",
@@ -32,7 +33,7 @@ makedocs(
3233
],
3334
"Comparison Against SymPy" => "comparison.md",
3435
"highlevel.md",
35-
"build_function",
36+
"build_function.md",
3637
"IR.md"
3738
]
3839
)

docs/src/tutorials/converting_to_C.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Automatic Conversion of Julia Code to C Functions
2+
3+
Since ModelingToolkit can trace Julia code into MTK IR that can be built and
4+
compiled via `build_function` to C, this gives us a nifty way to automatically
5+
generate C functions from Julia code! To see this in action, let's start with
6+
the Lotka-Volterra equations:
7+
8+
```julia
9+
using ModelingToolkit
10+
function lotka_volterra!(du, u, p, t)
11+
x, y = u
12+
α, β, δ, γ = p
13+
du[1] = dx = α*x - β*x*y
14+
du[2] = dy = -δ*y + γ*x*y
15+
end
16+
```
17+
18+
Now we trace this into ModelingToolkit:
19+
20+
```julia
21+
@variables t du[1:2] u[1:2] p[1:4]
22+
lotka_volterra!(du, u, p, t)
23+
```
24+
25+
which gives:
26+
27+
```julia
28+
du = Operation[p₁ * u₁ - (p₂ * u₁) * u₂, -p₃ * u₂ + (p₄ * u₁) * u₂]
29+
```
30+
31+
Now we build the equations we want to solve:
32+
33+
```julia
34+
eqs = @. D(u) ~ du
35+
36+
2-element Array{Equation,1}:
37+
Equation(derivative(u₁, t), p₁ * u₁ - (p₂ * u₁) * u₂)
38+
Equation(derivative(u₂, t), -p₃ * u₂ + (p₄ * u₁) * u₂)
39+
```
40+
41+
and then we build the function:
42+
43+
```julia
44+
build_function(eqs, u, p, t, target=ModelingToolkit.CTarget())
45+
46+
void diffeqf(double* du, double* RHS1, double* RHS2, double RHS3) {
47+
du[0] = RHS2[0] * RHS1[0] - (RHS2[1] * RHS1[0]) * RHS1[1];
48+
du[1] = -(RHS2[2]) * RHS1[1] + (RHS2[3] * RHS1[0]) * RHS1[1];
49+
}
50+
```
51+
52+
If we want to compile this, we do `expression=Val{false}`:
53+
54+
```julia
55+
f = build_function(eqs, u, p, t, target=ModelingToolkit.CTarget(),expression=Val{false})
56+
```
57+
58+
now we check it computes the same thing:
59+
60+
```julia
61+
du = rand(2); du2 = rand(2)
62+
u = rand(2)
63+
p = rand(4)
64+
t = rand()
65+
f(du,u,p,t)
66+
lotka_volterra!(du2, u, p, t)
67+
du == du2 # true!
68+
```

0 commit comments

Comments
 (0)