You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/tutorials/symbolic_functions.md
+29-33Lines changed: 29 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,14 +8,14 @@ The way to define symbolic variables is via the `@variables` macro:
8
8
```
9
9
10
10
After defining variables as symbolic, symbolic expressions, which we
11
-
call an `Operation`, can be generated by utilizing Julia expressions.
11
+
call a `Term`, can be generated by utilizing Julia expressions.
12
12
For example:
13
13
14
14
```julia
15
15
z = x^2+ y
16
16
```
17
17
18
-
Here, `z` is the `Operation` for "square `x` and add `y`". To
18
+
Here, `z` is the `Term` for "square `x` and add `y`". To
19
19
make an array of symbolic expressions, simply make an array of
20
20
symbolic expressions:
21
21
@@ -24,12 +24,14 @@ A = [x^2+y 0 2x
24
24
002y
25
25
y^2+x 00]
26
26
27
-
3×3 Array{Expression,2}:
28
-
x ^2+ y Constant(0) 2x
29
-
Constant(0) Constant(0) 2y
30
-
y ^2+ x Constant(0) Constant(0)
27
+
3×3 Array{Num,2}:
28
+
x ^2+ y 02x
29
+
002y
30
+
y ^2+ x 00
31
31
```
32
32
33
+
Note that by default, `@variables` returns `Sym` or `Term` objects wrapped in `Num` in order to make them behave like subtypes of `Real`. Any operation on these `Num` objects will return a new `Num` object, wrapping the result of computing symbolically on the underlying values.
34
+
33
35
To better view the results, we can use [Latexify.jl](https://github.com/korsbo/Latexify.jl).
34
36
ModelingToolkit.jl comes with Latexify recipes so it works automatically:
y ^ 2 + x & ModelingToolkit.Constant(0) & ModelingToolkit.Constant(0) \\
47
+
(x ^ 2) + y & 0 & 2 * x \\
48
+
0 & 0 & 2 * y \\
49
+
(y ^ 2) + x & 0 & 0 \\
48
50
\end{array}
49
51
\right]
50
52
\end{equation}
@@ -57,11 +59,11 @@ want to create the sparse version of `A` we would just call `sparse`:
57
59
using SparseArrays
58
60
spA =sparse(A)
59
61
60
-
3×3 SparseMatrixCSC{Expression,Int64} with 4 stored entries:
61
-
[1, 1] = x ^2+ y
62
-
[3, 1] = y ^2+ x
63
-
[1, 3] =2x
64
-
[2, 3] =2y
62
+
3×3 SparseMatrixCSC{Num,Int64} with 4 stored entries:
63
+
[1, 1] =(x ^2)+ y
64
+
[3, 1] =(y ^2)+ x
65
+
[1, 3] =2* x
66
+
[2, 3] =2* y
65
67
```
66
68
67
69
We can thus use normal Julia functions as generators for sparse
@@ -73,7 +75,7 @@ function f(u)
73
75
end
74
76
f([x,y,z]) # Recall that z = x^2 + y
75
77
76
-
3-element Array{Operation,1}:
78
+
3-element Array{Num,1}:
77
79
x - (x ^2+ y)
78
80
x ^2- y
79
81
(x ^2+ y) + y
@@ -85,7 +87,7 @@ Or we can build array variables and use these to trace:
85
87
@variables u[1:3]
86
88
f(u)
87
89
88
-
3-element Array{Operation,1}:
90
+
3-element Array{Num,1}:
89
91
u₁ - u₃
90
92
u₁ ^2- u₂
91
93
u₃ + u₂
@@ -178,7 +180,7 @@ a function via a sparse matrix. For example:
178
180
N =8
179
181
A =sparse(Tridiagonal([x^i for i in1:N-1],[x^i * y^(8-i) for i in1:N], [y^i for i in1:N-1]))
180
182
181
-
8×8 SparseMatrixCSC{Operation,Int64} with 22 stored entries:
183
+
8×8 SparseMatrixCSC{Num,Int64} with 22 stored entries:
182
184
[1, 1] = x ^1* y ^7
183
185
[2, 1] = x ^1
184
186
[1, 2] = y ^1
@@ -314,7 +316,7 @@ like:
314
316
```julia
315
317
ModelingToolkit.jacobian([x+x*y,x^2+y],[x,y])
316
318
317
-
2×2 Array{Expression,2}:
319
+
2×2 Array{Num,2}:
318
320
1+ y x
319
321
2x Constant(1)
320
322
```
@@ -338,7 +340,7 @@ This can be applied to arrays by using Julia's broadcast mechanism:
338
340
B =simplify.([t^2+t+t^22t+4t
339
341
x+y+y+2t x^2- x^2+ y^2])
340
342
341
-
2×2 Array{Operation,2}:
343
+
2×2 Array{Num,2}:
342
344
2* t ^2+ t 6t
343
345
x +2* (t + y) y ^2
344
346
```
@@ -348,7 +350,7 @@ We can then use `substitute` to change values of an expression around:
348
350
```julia
349
351
simplify.(substitute.(B,[x=>y^2]))
350
352
351
-
2×2 Array{Operation,2}:
353
+
2×2 Array{Num,2}:
352
354
2* t ^2+ t 6t
353
355
y ^2+2* (t + y) y ^2
354
356
```
@@ -380,8 +382,8 @@ the user's code. For these cases, ModelingToolkit.jl allows for fully
380
382
macro-free usage. For example:
381
383
382
384
```julia
383
-
x =Variable{Float64}(:x)()
384
-
y =Variable{Float64}(:y)()
385
+
x =Sym{Float64}(:x)()
386
+
y =Sym{Float64}(:y)()
385
387
x+y^2.0
386
388
```
387
389
@@ -396,23 +398,17 @@ convert the output to an `Expr`:
396
398
Expr(x+y^2)
397
399
```
398
400
399
-
## Variables as Operations
400
-
401
-
`Operation` is the type name the ModelingToolkit.jl gives to symbolic
402
-
expressions. In ModelingToolkit.jl, essentially everything is an
403
-
`Operation`. Notice that when we defined our variables above, they
404
-
were represented as an `Operation` as well, which means that variables
405
-
alone are an operation that can then be composed to make bigger
406
-
operations.
401
+
## `Sym`s and callable `Sym`s
407
402
408
-
But since variables are functions, we can represent their dependencies
409
-
as well. For example:
403
+
In the definition
410
404
411
405
```julia
412
406
@variables t x(t) y(t)
413
407
```
414
408
415
-
defines `t` as a dependent variable while `x(t)` and `y(t)` are
409
+
`t` is of type `Sym{Real}` but the name `x` refers to an object that represents the `Term``x(t)`. The operation of this expression is itself the object `Sym{FnType{Tuple{Real}, Real}}(:x)`. The type `Sym{FnType{...}}` represents a callable object. In this case specifically it's a function that takes 1 Real argument (noted by `Tuple{Real}`) and returns a `Real` result. You can call such a callable `Sym` with either a number or a symbolic expression of a permissible type.
410
+
411
+
this expression also defines `t` as a dependent variable while `x(t)` and `y(t)` are
416
412
independent variables. This is accounted for in differentiation:
0 commit comments