We can think of a variable as a piece of memory in a computer. A variable typically also has a name (also called a symbol). That name/symbol is used to refer to the variable; that is, the name / symbol is a handle on the variable. It is like the difference between you and your name.
There are different ways of creating a variable in
caracas
. One is as
which creates a SymPy variable a
but provides no handle
on it (no R-symbol). We can get an R-handle on a SymPy variable with
where we do something very confusing: Assign the R-name
a
to the SymPy variable b
and vice versa. We
can compute on variable b
in SymPy by manipulating the
symbol a
in R, e.g.
A text representation of a symbol can be found as:
a %>% print.default()
#> $pyobj
#> b + 1
#>
#> attr(,"class")
#> [1] "caracas_symbol"
a %>% as.character()
#> [1] "b + 1"
Usually, the best practice is to assign R symbols to SymPy variables of the same name. To avoid confusion, symbol names and Python variable names will always coincide.
In addition to symbol()
illustrated above, multiple
R-symbols / Python-variables can be defined using def_sym
and def_sym_vec
With this, R-symbols u
, v
, w
,
x
exist and each are connected to Python variables with the
same name
A third way for creating a symbol with as_sym
. First
notice:
as_sym("l1")
#> c: l₁
# same as symbol("l1")
l2 <- as_sym("l2"); l2
#> c: l₂
# same as def_sym("l2")
More interestingly
Above, r
is a \(4 \times
1\) matrix, while e.g. u
is an atom:
We can coerce between different “classes” (we quote the word because it is not a class system as e.g. those known from R) A text representation of the variables are:
While not often needed that are also lists and vectors in Python. In
caracas
they are created by coercion:
u %>% to_list()
#> c: [[u]]
u %>% to_vector()
#> c: [u]
m %>% to_list()
#> c: [[m₁], [m₂], [m₃], [m₄]]
m %>% to_vector()
#> c: [m₁, m₂, m₃, m₄]
The corresponding text representations are:
u %>% to_list() %>% as.character()
#> [1] "[[u]]"
u %>% to_vector() %>% as.character()
#> [1] "[u]"
m %>% to_list() %>% as.character()
#> [1] "[[m1], [m2], [m3], [m4]]"
m %>% to_vector() %>% as.character()
#> [1] "[m1, m2, m3, m4]"
Likewise:
def_sym('x', 'y')
eq <- 2*x^2 - x - y
eq
#> c: 2
#> 2⋅x - x - y
as.character(eq)
#> [1] "2*x^2 - x - y"
as_expr(eq)
#> expression(2 * x^2 - x - y)
tex(eq)
#> [1] "2 x^{2} - x - y"
\[2 x^{2} - x - y\]
sol <- solve_sys(eq, x)
sol
#> x = _________
#> 1 ╲╱ 8⋅y + 1
#> ─ - ───────────
#> 4 4
#> x = _________
#> ╲╱ 8⋅y + 1 1
#> ─────────── + ─
#> 4 4
# Access solutions
sol[[1]]$x
#> c: _________
#> 1 ╲╱ 8⋅y + 1
#> ─ - ───────────
#> 4 4
sol[[2]]$x
#> c: _________
#> ╲╱ 8⋅y + 1 1
#> ─────────── + ─
#> 4 4
dx <- der(eq, x)
dx
#> c: 4⋅x - 1
dx %>% symbol_class()
#> [1] "atomic"
dxy <- der(eq, c(x, y))
dxy
#> c: [4⋅x - 1 -1]
dxy %>% symbol_class()
#> [1] "vector"
subs(eq, x, y)
#> c: 2
#> 2⋅y - 2⋅y
B_ <- matrix(c("x", 2, 0, "2*x"), 2, 2)
B <- as_sym(B_)
B
#> c: ⎡x 0 ⎤
#> ⎢ ⎥
#> ⎣2 2⋅x⎦
Binv <- inv(B) # or solve_lin(B)
Binv
#> c: ⎡ 1 ⎤
#> ⎢ ─ 0 ⎥
#> ⎢ x ⎥
#> ⎢ ⎥
#> ⎢-1 1 ⎥
#> ⎢─── ───⎥
#> ⎢ 2 2⋅x⎥
#> ⎣ x ⎦
tex(Binv)
#> [1] "\\left[\\begin{matrix}\\frac{1}{x} & 0\\\\- \\frac{1}{x^{2}} & \\frac{1}{2 x}\\end{matrix}\\right]"
det(B)
#> c: 2
#> 2⋅x
Binv * det(B)
#> c: ⎡2⋅x 0⎤
#> ⎢ ⎥
#> ⎣-2 x⎦
\[\left[\begin{matrix}\frac{1}{x} & 0\\- \frac{1}{x^{2}} & \frac{1}{2 x}\end{matrix}\right]\]
eigenval(Binv)
#> [[1]]
#> [[1]]$eigval
#> c: 1
#> ─
#> x
#>
#> [[1]]$eigmult
#> [1] 1
#>
#>
#> [[2]]
#> [[2]]$eigval
#> c: 1
#> ───
#> 2⋅x
#>
#> [[2]]$eigmult
#> [1] 1
eigenvec(Binv)
#> [[1]]
#> [[1]]$eigval
#> c: 1
#> ───
#> 2⋅x
#>
#> [[1]]$eigmult
#> [1] 1
#>
#> [[1]]$eigvec
#> c: [0 1]ᵀ
#>
#>
#> [[2]]
#> [[2]]$eigval
#> c: 1
#> ─
#> x
#>
#> [[2]]$eigmult
#> [1] 1
#>
#> [[2]]$eigvec
#> c: ⎡-x ⎤
#> ⎢─── 1⎥
#> ⎣ 2 ⎦ᵀ