# 03 - Objects in ‘caracas’

library(caracas)

## Variables, names, symbols etc.

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

symbol("a")
#> c: a

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

b <- symbol("a")
a <- symbol("b")

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 + 1
#> c: b + 1
a <- a + 1
a / b
#> c: b + 1
#>    ─────
#>      a

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. ## Creating symbols In addition to symbol() illustrated above, multiple R-symbols / Python-variables can be defined using def_sym and def_sym_vec def_sym(u, v) def_sym("w", "x") def_sym_vec(c("y", "z")) With this, R-symbols u, v, w, x exist and each are connected to Python variables with the same name u; v; w; x; y; z #> c: u #> c: v #> c: w #> c: x #> c: y #> c: z 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 m_ <- paste0("m", 1:4) m <- as_sym(m_) m #> c: [m₁ m₂ m₃ m₄]ᵀ B_ <- matrix(c("x", 2, 0, "2*x"), 2, 2) B <- as_sym(B_) ## Classes Above, r is a $$4 \times 1$$ matrix, while e.g. u is an atom: m %>% symbol_class() #> [1] "matrix" u %>% symbol_class() #> [1] "atomic" 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: m %>% as.character() #> [1] "Matrix([[m1], [m2], [m3], [m4]])" u %>% as.character() #> [1] "u" 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: m %>% to_matrix() #> c: [m₁ m₂ m₃ m₄]ᵀ u %>% to_matrix() #> c: [u] ## Indexing Let v <- m %>% to_vector() l <- m %>% to_list() V <- matrix_sym(2, 2) ## Quick start 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 #> Solution 1: #> x = _________ #> 1 ╲╱ 8⋅y + 1 #> ─ - ─────────── #> 4 4 #> Solution 2: #> 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 ## Linear algebra 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    ⎦ᵀ