--- title: "03 - Objects in 'caracas'" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{03 - Objects in 'caracas'} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r, message=FALSE} library(caracas) ``` ```{r, include = FALSE} inline_code <- function(x) { x } if (!has_sympy()) { # SymPy not available, so the chunks shall not be evaluated knitr::opts_chunk$set(eval = FALSE) inline_code <- function(x) { deparse(substitute(x)) } } ``` ## 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 ```{r} symbol("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 ```{r} 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. ```{r} a + 1 a <- a + 1 a / b ``` A text representation of a symbol can be found as: ```{r} a %>% print.default() a %>% as.character() ``` 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` ```{r} 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 ```{r} u; v; w; x; y; z ``` A third way for creating a symbol with `as_sym`. First notice: ```{r} as_sym("l1") # same as symbol("l1") l2 <- as_sym("l2"); l2 # same as def_sym("l2") ``` More interestingly ```{r} m_ <- paste0("m", 1:4) m <- as_sym(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: ```{r} m %>% symbol_class() u %>% symbol_class() ``` 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: ```{r} m %>% as.character() u %>% as.character() ``` While not often needed that are also lists and vectors in Python. In `caracas` they are created by coercion: ```{r} u %>% to_list() u %>% to_vector() m %>% to_list() m %>% to_vector() ``` The corresponding text representations are: ```{r} u %>% to_list() %>% as.character() u %>% to_vector() %>% as.character() m %>% to_list() %>% as.character() m %>% to_vector() %>% as.character() ``` Likewise: ```{r} m %>% to_matrix() u %>% to_matrix() ``` ## Indexing Let ```{r} v <- m %>% to_vector() l <- m %>% to_list() V <- matrix_sym(2, 2) ``` ```{r} ``` ## Quick start ```{r} def_sym('x', 'y') eq <- 2*x^2 - x - y eq as.character(eq) as_expr(eq) tex(eq) ``` $$`r inline_code(tex(eq))`$$ ```{r} sol <- solve_sys(eq, x) sol # Access solutions sol[[1]]$x sol[[2]]$x dx <- der(eq, x) dx dx %>% symbol_class() dxy <- der(eq, c(x, y)) dxy dxy %>% symbol_class() subs(eq, x, y) ``` ## Linear algebra ```{r} B_ <- matrix(c("x", 2, 0, "2*x"), 2, 2) B <- as_sym(B_) B Binv <- inv(B) # or solve_lin(B) Binv tex(Binv) det(B) Binv * det(B) ``` $$`r inline_code(tex(Binv))`$$ ```{r} eigenval(Binv) eigenvec(Binv) ```