The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

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
#> 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

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    ⎦ᵀ

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.