99 - Reference

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(caracas)
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))
  }
}

Quick start

x <- symbol('x')
as.character(x)
x
as_expr(x)
2*x
y <- symbol('y')
sqrt(3*x^y)
z <- cos(x)^2 + sin(x)^2
z
simplify(z)
tex(z)
z <- cos(x)*cos(y) - sin(x)*sin(y)
z
simplify(z)
z <- cos(x + y)
z
expand(z)
expand_trig(z)
x <- symbol('x')
y <- symbol('y')
z <- log(x*y)
z
expand_log(z)

Sums

x <- symbol("x")
sum_(1/x, "x", 1, 10)
sum_(1/x, x, 1, 10)
s <- sum_(1/x, "x", 1, 10)
as_expr(s)
sum(1/(1:10))
n <- symbol("n")
simplify(sum_(x, x, 1, n))

Products

x <- symbol("x")
p <- prod_(1/x, "x", 1, 10)
p
as_expr(p)
prod(1/(1:10))
n <- symbol("n")
prod_(x, x, 1, n)

Integrals

x <- symbol("x")

int(1/x, x, 1, 10)
i1 <- int(1/x, x, 1, 10, doit = FALSE)
i1
tex(i1)
doit(i1)
int(1/x, x)
i1 <- int(1/x, x, doit = FALSE)
i1
tex(i1)
doit(i1)

Limits

x <- symbol("x")
lim(sin(x)/x, "x", 0)
lim(1/x, "x", 0, dir = '+')
lim(1/x, "x", 0, dir = '-')

We can also postpone evaluation:

x <- symbol("x")
lim(sin(x)/x, "x", 0)
lim(sin(x)/x, x, 0)
res <- lim(sin(x)/x, "x", 0, doit = FALSE)
res
as.character(res)
tex(res)
doit(res)
as_expr(res)

Derivatives

Note that the function is called d() and not deriv().

x <- symbol("x")
y <- symbol("y")
f <- 3*x^2 + x*y^2
f
as_expr(f)
der(f, "x")
der(f, x)
der(f, c("x", "y"))
der(f, list(x, y))
f1 <- der(f, list(x, y))
f1
as.character(f1)
as_expr(f1)
eval(as_expr(f1), list(x = 1, y = 2))
der(f1, list(x, y))
f2 <- der2(f, list(x, y))
f2
as_expr(f2)
eval(as_expr(f2), list(x = 1, y = 2))
x <- symbol("x")
y <- symbol("y")
f <- eval_to_symbol("[3*x**2 + x*y**2, 2*x, 5*y]")
f
der(f, list(x, y))

Taylor expansion

def_sym(x)
f <- cos(x)
ft_with_O <- taylor(f, x0 = 0, n = 4+1)
ft_with_O
ft_with_O %>% drop_remainder() %>% as_expr()

Linear algebra

A <- matrix(c("x", 0, 0, "2*x"), 2, 2)
A
B <- as_sym(A)
B
2*B
B*B # Component-wise / Hadamard product
dim(B)
sqrt(B)
log(B)
sum(B)
B %*% t(B)
diag(B)
cbind(B, B)
rbind(B, B)
det(B)
QRdecomposition(B)
A <- matrix(c("a", 0, 0, 0, "a", "a", "a", 0, 0), 3, 3)
B <- as_sym(A)
eigenval(B)
eigenvec(B)
eigen(eval(as_expr(B), list(a = 2)))
B
diag(B)
diag(B) <- "b"
B
diag(B)[-2] <- "a"
B

Solve

Below find an example with maximising the multinomial likelihood.

p <- as_sym(paste0("p", 1:3))
y <- as_sym(paste0("y", 1:3))
a <- as_sym("a")
l <- sum(y*log(p))
l
L <- -l + a*(sum(p) - 1)
L
tex(L)
g <- der(L, list(p, a))
g
sol <- solve_sys(g, list(p, a))
sol
sol[[1L]]$p1
tex(sol[[1L]]$p1)

Assumptions

x <- symbol("x", positive = TRUE)
solve_sys(x^2 - 1, 0, x)

x <- symbol("x", real = TRUE)
solve_sys(x^2 + 1, 0, x)

x <- symbol("x")
solve_sys(x^2 + 1, 0, x)

Substitution

x <- symbol('x')
eq <- 2*x^2 - x
eq
subs(eq, x, "y")
p <- as_sym(paste0("p", 1:3))
y <- as_sym(paste0("y", 1:3))
a <- as_sym("a")
l <- sum(y*log(p))
L <- -l + a*(sum(p) - 1)
g <- der(L, c(a, p))
sols <- solve_sys(g, list(a, p))
sol <- sols[[1L]]
sol
H <- der2(L, list(p, a))
H
H_sol <- subs(H, sol)
H_sol

Subsetting

Note that all vectors in caracas are column vectors.

A <- matrix(c("a", 0, 0, 0, "a", "a", "a", 0, 0), 3, 3)
B <- as_sym(A)
B[, 2]
B[, -2]
B[1, ]
B[1, , drop = FALSE] # Note this is a 1x3 matrix
B[, 2] <- "x"
B

Interactively show $\LaTeX$ representation

texshow(B)

plots the following in the plot window:

texshow(B)

You can also provide a string instead:

texshow(paste0("B = ", tex(B)))

giving

texshow(paste0("B = ", tex(B)))

Using SymPy directly

sympy <- get_sympy()
sympy$diff("2*a*x", "x")
sympy$solve("x**2 - 1", "x")

Assumptions

Below we give a brief example of assumptions. First consider the Cholesky decomposition of a matrix:

A <- matrix(c("x+1", 1, 1, 1), 2, 2) %>% as_sym()
A
do_la(A, "cholesky")

This fails as A is not positive (semi-)definite.

To ensure this, we need to impose restrictions on x. This is done by defining a symbol with an assumption about positivity:

y <- symbol("y", positive = TRUE)

We continue and define B, where it is important that declare_symbols = FALSE or else a new y will automatically be defined by caracas overwriting the above definition:

B <- as_sym("[[y + 1, 1], [1, 1]]", declare_symbols = FALSE)
B
do_la(B, "cholesky")

It is possible to ask for properties (see https://docs.sympy.org/latest/modules/assumptions/ask.html):

ask(y, "positive")
ask(B, "hermitian")
ask(A, "hermitian")

Output

# Multinomial likelihood
p <- as_sym(paste0("p", 1:3))
y <- as_sym(paste0("y", 1:3))
a <- as_sym("a")
l <- sum(y*log(p))
L <- -l + a*(sum(p) - 1)
L
print(L, ascii = TRUE)
g <- der(L, list(p, a))
sol <- solve_sys(g, list(p, a))
sol
print(sol, simplify = FALSE)
as.character(g)
as_character_matrix(g)

Options

The following options are available:

sol
L
options(caracas.print.method = "prettyascii") 
sol
L
options(caracas.print.method = "ascii") 
sol
L
options(caracas.print.method = NULL) # Or 'utf8' 
sol
L
p
options(caracas.print.rowvec = FALSE)
p
options(caracas.print.rowvec = NULL) # reset to default (TRUE)
sol
options(caracas.print.sol.simplify = FALSE)
sol
options(caracas.print.sol.simplify = NULL) # reset to default (TRUE)


Try the caracas package in your browser

Any scripts or data that you put into this service are public.

caracas documentation built on June 22, 2024, 10:59 a.m.