| Title: | Computer Algebra |
|---|---|
| Description: | Computer algebra via the 'SymPy' library (<https://www.sympy.org/>). This makes it possible to solve equations symbolically, find symbolic integrals, symbolic sums and other important quantities. |
| Authors: | Mikkel Meyer Andersen [aut, cre, cph], Søren Højsgaard [aut, cph] |
| Maintainer: | Mikkel Meyer Andersen <[email protected]> |
| License: | GPL |
| Version: | 2.1.2.9004 |
| Built: | 2026-05-27 07:36:07 UTC |
| Source: | https://github.com/r-cas/caracas |
Extract or replace parts of an object
## S3 method for class 'caracas_symbol' x[i, j, ..., drop = TRUE]## S3 method for class 'caracas_symbol' x[i, j, ..., drop = TRUE]
x |
A |
i |
row indices specifying elements to extract or replace |
j |
column indices specifying elements to extract or replace |
... |
Not used |
drop |
Simplify dimensions of resulting object |
if (has_sympy()) { A <- matrix(c("a", 0, 0, 0, "a", "a", "a", 0, 0), 3, 3) B <- as_sym(A) B[1:2, ] B[, 2] B[2, , drop = FALSE] }if (has_sympy()) { A <- matrix(c("a", 0, 0, 0, "a", "a", "a", 0, 0), 3, 3) B <- as_sym(A) B[1:2, ] B[, 2] B[2, , drop = FALSE] }
Extract or replace parts of an object
## S3 replacement method for class 'caracas_symbol' x[i, j, ...] <- value## S3 replacement method for class 'caracas_symbol' x[i, j, ...] <- value
x |
A |
i |
row indices specifying elements to extract or replace |
j |
column indices specifying elements to extract or replace |
... |
Not used |
value |
Replacement value |
if (has_sympy()) { A <- matrix(c("a", 0, 0, 0, "a", "a", "a", 0, 0), 3, 3) B <- as_sym(A) B[, 2] <- "x" B[, 3] <- vector_sym(3) B }if (has_sympy()) { A <- matrix(c("a", 0, 0, 0, "a", "a", "a", 0, 0), 3, 3) B <- as_sym(A) B[, 2] <- "x" B[, 3] <- vector_sym(3) B }
Add prefix to each element of matrix
add_prefix(x, prefix = "")add_prefix(x, prefix = "")
x |
Numeric or symbolic matrix |
prefix |
A character vector |
if (has_sympy()) { X <- matrix_sym(2, 3) X add_prefix(X, "e") X <- matrix(1:6, 3, 2) X add_prefix(X, "e") }if (has_sympy()) { X <- matrix_sym(2, 3) X add_prefix(X, "e") X <- matrix(1:6, 3, 2) X add_prefix(X, "e") }
Return all variables in caracas symbol
all_vars(x)all_vars(x)
x |
caracas symbol |
if (has_sympy()){ x <- vector_sym(5) all_vars(x) }if (has_sympy()){ x <- vector_sym(5) all_vars(x) }
apart() performs a partial fraction decomposition on a rational function
apart(x)apart(x)
x |
A |
if (has_sympy()){ def_sym(x) expr = (4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x) apart(expr) }if (has_sympy()){ def_sym(x) expr = (4*x**3 + 21*x**2 + 10*x + 12)/(x**4 + 5*x**3 + 5*x**2 + 4*x) apart(expr) }
Coerce symbol to character
as_character(x)as_character(x)
x |
caracas symbol |
Get matrix as character matrix
as_character_matrix(x)as_character_matrix(x)
x |
caracas symbol |
if (has_sympy()) { s <- as_sym("[[r1, r2, r3], [u1, u2, u3]]") s2 <- apply(as_character_matrix(s), 2, function(x) (paste("1/(", x, ")"))) as_sym(s2) }if (has_sympy()) { s <- as_sym("[[r1, r2, r3], [u1, u2, u3]]") s2 <- apply(as_character_matrix(s), 2, function(x) (paste("1/(", x, ")"))) as_sym(s2) }
Construct diagonal matrix from vector
as_diag(x)as_diag(x)
x |
Matrix with 1 row or 1 column that is the diagonal in a new diagonal matrix |
if (has_sympy()) { d <- as_sym(c("a", "b", "c")) D <- as_diag(d) D }if (has_sympy()) { d <- as_sym(c("a", "b", "c")) D <- as_diag(d) D }
Potentially calls doit().
as_expr(x, first_doit = TRUE) ## S3 method for class 'caracas_symbol' as.expression(x, ...) ## S3 method for class 'caracas_solve_sys_sol' as.expression(x, ...)as_expr(x, first_doit = TRUE) ## S3 method for class 'caracas_symbol' as.expression(x, ...) ## S3 method for class 'caracas_solve_sys_sol' as.expression(x, ...)
x |
caracas_symbol |
first_doit |
Try |
... |
not used |
if (has_sympy()) { v <- vector_sym(2) x <- as_expr(v) x y <- as.expression(v) y }if (has_sympy()) { v <- vector_sym(2) x <- as_expr(v) x y <- as.expression(v) y }
Convert expression into function object.
as_func(x, order = NULL, vec_arg = FALSE) ## S3 method for class 'caracas_symbol' as.function(x, ...)as_func(x, order = NULL, vec_arg = FALSE) ## S3 method for class 'caracas_symbol' as.function(x, ...)
x |
caracas expression. |
order |
desired order of function argument. Defaults to alphabetical ordering. |
vec_arg |
should the function take vector valued argument. |
... |
not used |
if (has_sympy()) { def_sym(b0, b1, b2, k, x) e <- b1 + (b0 - b1)*exp(-k*x) + b2*x f1 <- as_func(e) f1 f1(1, 2, 3, 4, 5) f1 <- as_func(e, order = sort(all_vars(e))) f1(1, 2, 3, 4, 5) f2 <- as_func(e, vec_arg = TRUE) f2 f2(c(1, 2, 3, 4, 5)) f2 <- as_func(e, order = sort(all_vars(e)), vec_arg = TRUE) f2 f2(c(1,2,3,4,5)) f1a <- as.function(e) f1a f1a(c(1, 2, 3, 4, 5)) f1(1, 2, 3, 4, 5) }if (has_sympy()) { def_sym(b0, b1, b2, k, x) e <- b1 + (b0 - b1)*exp(-k*x) + b2*x f1 <- as_func(e) f1 f1(1, 2, 3, 4, 5) f1 <- as_func(e, order = sort(all_vars(e))) f1(1, 2, 3, 4, 5) f2 <- as_func(e, vec_arg = TRUE) f2 f2(c(1, 2, 3, 4, 5)) f2 <- as_func(e, order = sort(all_vars(e)), vec_arg = TRUE) f2 f2(c(1,2,3,4,5)) f1a <- as.function(e) f1a f1a(c(1, 2, 3, 4, 5)) f1(1, 2, 3, 4, 5) }
Variables are detected as a character followed by a number of either: character, number or underscore.
as_sym(x, declare_symbols = TRUE)as_sym(x, declare_symbols = TRUE)
x |
R object to convert to a symbol |
declare_symbols |
declare detected symbols automatically |
Default is to declare used variables. Alternatively, the user
must declare them first, e.g. by symbol().
Note that matrices can be defined by specifying a Python matrix, see below in examples.
if (has_sympy()) { x <- symbol("x") A <- matrix(c("x", 0, 0, "2*x"), 2, 2) A B <- as_sym(A) B 2 * B dim(B) sqrt(B) D <- as_sym("[[1, 4, 5], [-5, 8, 9]]") D }if (has_sympy()) { x <- symbol("x") A <- matrix(c("x", 0, 0, "2*x"), 2, 2) A B <- as_sym(A) B 2 * B dim(B) sqrt(B) D <- as_sym("[[1, 4, 5], [-5, 8, 9]]") D }
Stacks matrix to vector
as_vec(x)as_vec(x)
x |
Matrix |
if (has_sympy()) { A <- as_sym(matrix(1:9, 3)) as_vec(A) }if (has_sympy()) { A <- as_sym(matrix(1:9, 3)) as_vec(A) }
Convert symbol to character
## S3 method for class 'caracas_symbol' as.character(x, replace_I = TRUE, ...)## S3 method for class 'caracas_symbol' as.character(x, replace_I = TRUE, ...)
x |
A |
replace_I |
Replace constant I (can both be identity and imaginary unit) |
... |
not used |
Ask for a symbol's property
ask(x, property)ask(x, property)
x |
symbol |
property |
property, e.g. 'positive' |
if (has_sympy()) { x <- symbol("x", positive = TRUE) ask(x, "positive") }if (has_sympy()) { x <- symbol("x", positive = TRUE) ask(x, "positive") }
Creates block diagonal caracas matrix
bdiag_(...)bdiag_(...)
... |
Elements to be put on diagonals |
a caracas matrix
Søren Højsgaard
cancel() will take any rational function and put it into the standard canonical form
cancel(x)cancel(x)
x |
A |
if (has_sympy()){ def_sym(x, y, z) expr = cancel((x**2 + 2*x + 1)/(x**2 + x)) cancel(expr) expr = (x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2)/(x**2 - 1) cancel(expr) factor_(expr) }if (has_sympy()){ def_sym(x, y, z) expr = cancel((x**2 + 2*x + 1)/(x**2 + x)) cancel(expr) expr = (x*y**2 - 2*x*y*z + x*z**2 + y**2 - 2*y*z + z**2)/(x**2 - 1) cancel(expr) factor_(expr) }
Collects common powers of a term in an expression
collect(x, a)collect(x, a)
x, a
|
A |
if (has_sympy()){ def_sym(x, y, z) expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3 collect(expr, x) }if (has_sympy()){ def_sym(x, y, z) expr = x*y + x - 3 + 2*x**2 - z*x**2 + x**3 collect(expr, x) }
Column space (range) of a symbolic matrix
colspan(x)colspan(x)
x |
Symbolic matrix |
if (has_sympy()) { X1 <- matrix_(paste0("x_",c(1,1,1,1, 2,2,2,2, 3,4,3,4)), nrow = 4) X1 colspan(X1) do_la(X1, "columnspace") rankMatrix_(X1) X2 <- matrix_(paste0("x_",c(1,1,1,1, 0,0,2,2, 3,4,3,4)), nrow = 4) X2 colspan(X2) do_la(X2, "columnspace") rankMatrix_(X2) }if (has_sympy()) { X1 <- matrix_(paste0("x_",c(1,1,1,1, 2,2,2,2, 3,4,3,4)), nrow = 4) X1 colspan(X1) do_la(X1, "columnspace") rankMatrix_(X1) X2 <- matrix_(paste0("x_",c(1,1,1,1, 0,0,2,2, 3,4,3,4)), nrow = 4) X2 colspan(X2) do_la(X2, "columnspace") rankMatrix_(X2) }
Cumulative Sums
## S3 method for class 'caracas_symbol' cumsum(x)## S3 method for class 'caracas_symbol' cumsum(x)
x |
Elements to sum |
if (has_sympy()) { A <- matrix(1:9, 3) cumsum(A) B <- matrix_sym(3, 3) cumsum(B) C <- vector_sym(3) cumsum(C) }if (has_sympy()) { A <- matrix(1:9, 3) cumsum(A) B <- matrix_sym(3, 3) cumsum(B) C <- vector_sym(3) cumsum(C) }
Define (invisibly) caracas symbols in global environment
Define symbol for components in vector
def_sym(..., charvec = NULL, warn = FALSE, env = parent.frame()) def_sym_vec(x, env = parent.frame())def_sym(..., charvec = NULL, warn = FALSE, env = parent.frame()) def_sym_vec(x, env = parent.frame())
... |
Names for new symbols, also supports non-standard evaluation |
charvec |
Take each element in this character vector and define as caracas symbols |
warn |
Warn if existing variable names are overwritten |
env |
The environment in which the assignment is made. |
x |
Character vector. |
Names of declared variables (invisibly)
if (has_sympy()) { ls() def_sym(n1, n2, n3) ls() def_sym("x1", "x2", "x3") ls() # def_sym("x1", "x2", "x3", warn = TRUE) # Do not run as will cause a warning ls() def_sym(i, j, charvec = c("x", "y")) ls() } if (has_sympy()) { def_sym(z1, z2, z3) u <- paste0("u", seq_len(3)) ## Creates symbols u1, u2, u3 and binds to names u1, u2, u3 in R. def_sym_vec(u) ## Same as (but easier than) def_sym(u1, u2, u3) ## Notice: this creates matrix [u1, u2, u3] as_sym(u) }if (has_sympy()) { ls() def_sym(n1, n2, n3) ls() def_sym("x1", "x2", "x3") ls() # def_sym("x1", "x2", "x3", warn = TRUE) # Do not run as will cause a warning ls() def_sym(i, j, charvec = c("x", "y")) ls() } if (has_sympy()) { def_sym(z1, z2, z3) u <- paste0("u", seq_len(3)) ## Creates symbols u1, u2, u3 and binds to names u1, u2, u3 in R. def_sym_vec(u) ## Same as (but easier than) def_sym(u1, u2, u3) ## Notice: this creates matrix [u1, u2, u3] as_sym(u) }
Symbolic differentiation of an expression
der(expr, vars, simplify = TRUE)der(expr, vars, simplify = TRUE)
expr |
A |
vars |
variables to take derivate with respect to |
simplify |
Simplify result |
if (has_sympy()) { x <- symbol("x") y <- symbol("y") f <- 3*x^2 + x*y^2 der(f, x) g <- der(f, list(x, y)) g dim(g) G <- matrify(g) G dim(G) h <- der(g, list(x, y)) h dim(h) as.character(h) H <- matrify(h) H dim(H) g |> der(list(x, y), simplify = FALSE) |> der(list(x, y), simplify = FALSE) |> der(list(x, y), simplify = FALSE) }if (has_sympy()) { x <- symbol("x") y <- symbol("y") f <- 3*x^2 + x*y^2 der(f, x) g <- der(f, list(x, y)) g dim(g) G <- matrify(g) G dim(G) h <- der(g, list(x, y)) h dim(h) as.character(h) H <- matrify(h) H dim(H) g |> der(list(x, y), simplify = FALSE) |> der(list(x, y), simplify = FALSE) |> der(list(x, y), simplify = FALSE) }
Symbolic differentiation of second order of an expression
der2(expr, vars, simplify = TRUE)der2(expr, vars, simplify = TRUE)
expr |
A |
vars |
variables to take derivate with respect to |
simplify |
Simplify result |
if (has_sympy()) { x <- symbol("x") y <- symbol("y") f <- 3*x^2 + x*y^2 der2(f, x) h <- der2(f, list(x, y)) h dim(h) H <- matrify(h) H dim(H) }if (has_sympy()) { x <- symbol("x") y <- symbol("y") f <- 3*x^2 + x*y^2 der2(f, x) h <- der2(f, list(x, y)) h dim(h) H <- matrify(h) H dim(H) }
Symbolic determinant (and log-determinant) for caracas_symbol.
## S4 method for signature 'caracas_symbol,logical' determinant(x, logarithm = TRUE, ...) ## S4 method for signature 'caracas_symbol,missing' determinant(x, logarithm = TRUE, ...)## S4 method for signature 'caracas_symbol,logical' determinant(x, logarithm = TRUE, ...) ## S4 method for signature 'caracas_symbol,missing' determinant(x, logarithm = TRUE, ...)
x |
A |
logarithm |
Logical; if |
... |
Unused. |
An object of class "det" with components modulus, sign,
and logarithm.
Symbolic diagonal matrix
diag_(x, n = 1L, declare_symbols = TRUE, ...)diag_(x, n = 1L, declare_symbols = TRUE, ...)
x |
Character vector with diagonal |
n |
Number of times |
declare_symbols |
Passed on to |
... |
Passed on to |
if (has_sympy()) { diag_(c(1,3,5)) diag_(c("a", "b", "c")) diag_("a", 2) diag_(vector_sym(4)) }if (has_sympy()) { diag_(c(1,3,5)) diag_(c("a", "b", "c")) diag_("a", 2) diag_(vector_sym(4)) }
Replace matrix diagonal
diag(x) <- valuediag(x) <- value
x |
Object |
value |
Replacement value |
Matrix diagonal
## S4 method for signature 'caracas_symbol' diag(x)## S4 method for signature 'caracas_symbol' diag(x)
x |
Object |
Replace diagonal
## S3 replacement method for class 'caracas_symbol' diag(x) <- value## S3 replacement method for class 'caracas_symbol' diag(x) <- value
x |
A |
value |
Replacement value |
if (has_sympy()) { A <- matrix(c("a", 0, 0, 0, "a", "a", "a", 0, 0), 3, 3) B <- as_sym(A) B diag(B) diag(B) <- "b" B diag(B) }if (has_sympy()) { A <- matrix(c("a", 0, 0, 0, "a", "a", "a", 0, 0), 3, 3) B <- as_sym(A) B diag(B) diag(B) <- "b" B diag(B) }
Difference matrix
diff_mat(N, l = "-1", d = 1)diff_mat(N, l = "-1", d = 1)
N |
Number of rows (and columns) |
l |
Value / symbol below main diagonal |
d |
Value / symbol on main diagonal |
if (has_sympy()){ Dm <- diff_mat(4) Dm y <- vector_sym(4, "y") Dm %*% y }if (has_sympy()){ Dm <- diff_mat(4) Dm y <- vector_sym(4, "y") Dm %*% y }
Dimensions of a caracas symbol
## S3 method for class 'caracas_symbol' dim(x)## S3 method for class 'caracas_symbol' dim(x)
x |
caracas symbol |
Dimensions of a caracas symbol
## S3 replacement method for class 'caracas_symbol' dim(x) <- value## S3 replacement method for class 'caracas_symbol' dim(x) <- value
x |
caracas symbol |
value |
new dimension |
if (has_sympy()) { v <- vector_sym(4) v dim(v) dim(v) <- c(2, 2) v m <- matrix_sym(2, 2) dim(m) dim(m) <- c(4, 1) m }if (has_sympy()) { v <- vector_sym(4) v dim(v) dim(v) <- c(2, 2) v m <- matrix_sym(2, 2) dim(m) dim(m) <- c(4, 1) m }
Do linear algebra operation
do_la(x, slot, ...)do_la(x, slot, ...)
x |
A matrix for which a property is requested |
slot |
The property requested |
... |
Auxillary arguments |
Returns the requested property of a matrix.
if (has_sympy()) { A <- matrix(c("a", "0", "0", "1"), 2, 2) |> as_sym() do_la(A, "QR") QRdecomposition(A) do_la(A, "LU") LUdecomposition(A) do_la(A, "cholesky", hermitian = FALSE) chol(A, hermitian = FALSE) do_la(A, "singular_value_decomposition") do_la(A, "svd") svd_res <- svd_(A) svd_res U_expr <- svd_res$U |> as_expr() U_expr eval(U_expr, list(a = 3+2i)) b <- symbol("b", real = TRUE) B <- matrix(c("b", "0", "0", "1"), 2, 2) |> as_sym(declare_symbols = FALSE) svd_(B) do_la(A, "eigenval") eigenval(A) do_la(A, "eigenvec") eigenvec(A) do_la(A, "inv") inv(A) do_la(A, "trace") trace_(A) do_la(A, "echelon_form") do_la(A, "rank") do_la(A, "det") # Determinant det(A) }if (has_sympy()) { A <- matrix(c("a", "0", "0", "1"), 2, 2) |> as_sym() do_la(A, "QR") QRdecomposition(A) do_la(A, "LU") LUdecomposition(A) do_la(A, "cholesky", hermitian = FALSE) chol(A, hermitian = FALSE) do_la(A, "singular_value_decomposition") do_la(A, "svd") svd_res <- svd_(A) svd_res U_expr <- svd_res$U |> as_expr() U_expr eval(U_expr, list(a = 3+2i)) b <- symbol("b", real = TRUE) B <- matrix(c("b", "0", "0", "1"), 2, 2) |> as_sym(declare_symbols = FALSE) svd_(B) do_la(A, "eigenval") eigenval(A) do_la(A, "eigenvec") eigenvec(A) do_la(A, "inv") inv(A) do_la(A, "trace") trace_(A) do_la(A, "echelon_form") do_la(A, "rank") do_la(A, "det") # Determinant det(A) }
Perform calculations setup previously
doit(x)doit(x)
x |
A |
if (has_sympy()) { x <- symbol('x') res <- lim(sin(x)/x, "x", 0, doit = FALSE) res doit(res) }if (has_sympy()) { x <- symbol('x') res <- lim(sin(x)/x, "x", 0, doit = FALSE) res doit(res) }
Remove remainder term
drop_remainder(x)drop_remainder(x)
x |
Expression to remove remainder term from |
if (has_sympy()) { 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() }if (has_sympy()) { 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() }
Create a symbol from a string
eval_to_symbol(x)eval_to_symbol(x)
x |
String to evaluate |
A caracas_symbol
if (has_sympy()) { x <- symbol('x') (1+1)*x^2 lim(sin(x)/x, "x", 0) }if (has_sympy()) { x <- symbol('x') (1+1)*x^2 lim(sin(x)/x, "x", 0) }
Expand a function expression
expand_func(x)expand_func(x)
x |
A |
Note that force as described at
https://docs.sympy.org/latest/tutorial/simplification.html#expand-log is used
meaning that some assumptions are taken.
expand_log(x)expand_log(x)
x |
A |
if (has_sympy()) { x <- symbol('x') y <- symbol('y') z <- log(x*y) z expand_log(z) }if (has_sympy()) { x <- symbol('x') y <- symbol('y') z <- log(x*y) z expand_log(z) }
Expand a trigonometric expression
expand_trig(x)expand_trig(x)
x |
A |
Expand expression
factor_(x)factor_(x)
x |
A |
if (has_sympy()){ def_sym(x, y, z) factor_(x**3 - x**2 + x - 1) factor_(x**2*z + 4*x*y*z + 4*y**2*z) }if (has_sympy()){ def_sym(x, y, z) factor_(x**3 - x**2 + x - 1) factor_(x**2*z + 4*x*y*z + 4*y**2*z) }
Get numerator and denominator of a fraction
fraction_parts(x) numerator(x) denominator(x)fraction_parts(x) numerator(x) denominator(x)
x |
Fraction |
if (has_sympy()) { x <- as_sym("a/b") frac <- fraction_parts(x) frac frac$numerator frac$denominator }if (has_sympy()) { x <- as_sym("a/b") frac <- fraction_parts(x) frac frac$numerator frac$denominator }
Get free symbol in expression
free_symbols(x)free_symbols(x)
x |
Expression in which to get the free symbols in |
if (has_sympy()) { def_sym(a, b) x <- (a - b)^4 free_symbols(x) }if (has_sympy()) { def_sym(a, b) x <- (a - b)^4 free_symbols(x) }
Generate generic vectors and matrices.
vector_sym(n, entry = "v") matrix_sym(nrow, ncol, entry = "v") matrix_sym_diag(nrow, entry = "v") matrix_sym_symmetric(nrow, entry = "v")vector_sym(n, entry = "v") matrix_sym(nrow, ncol, entry = "v") matrix_sym_diag(nrow, entry = "v") matrix_sym_symmetric(nrow, entry = "v")
n |
Length of vector |
entry |
The symbolic name of each entry. |
nrow, ncol
|
Number of rows and columns |
if (has_sympy()) { vector_sym(4, "b") matrix_sym(3, 2, "a") matrix_sym_diag(4, "s") matrix_sym_symmetric(4, "s") }if (has_sympy()) { vector_sym(4, "b") matrix_sym(3, 2, "a") matrix_sym_diag(4, "s") matrix_sym_symmetric(4, "s") }
Get basis
get_basis(x)get_basis(x)
x |
caracas vector / matrix |
if (has_sympy()) { x <- vector_sym(3) get_basis(x) W <- matrix(c("r_1", "r_1", "r_2", "r_2", "0", "0", "u_1", "u_2"), nrow=4) W <- as_sym(W) get_basis(W) }if (has_sympy()) { x <- vector_sym(3) get_basis(x) W <- matrix(c("r_1", "r_1", "r_2", "r_2", "0", "0", "u_1", "u_2"), nrow=4) W <- as_sym(W) get_basis(W) }
Get the 'py' object. Note that it gives you extra responsibilities when you choose to access the 'py' object directly.
get_py()get_py()
The 'py' object with direct access to the library.
if (has_sympy()) { py <- get_py() }if (has_sympy()) { py <- get_py() }
Get the 'SymPy' object. Note that it gives you extra responsibilities when you choose to access the 'SymPy' object directly.
get_sympy()get_sympy()
The 'SymPy' object with direct access to the library.
if (has_sympy()) { sympy <- get_sympy() sympy$solve("x**2-1", "x") }if (has_sympy()) { sympy <- get_sympy() sympy$solve("x**2-1", "x") }
Check if 'SymPy' is available
has_sympy()has_sympy()
TRUE if 'SymPy' is available, else FALSE
has_sympy()has_sympy()
Head and tail for caracas matrices
## S3 method for class 'caracas_symbol' head(x, n = 6, ...) ## S3 method for class 'caracas_symbol' tail(x, n = 6, ...)## S3 method for class 'caracas_symbol' head(x, n = 6, ...) ## S3 method for class 'caracas_symbol' tail(x, n = 6, ...)
x |
A caracas object |
n |
Number of rows to be extracted |
... |
Not used |
An object of same class as x
Søren Højsgaard
Install the 'SymPy' Python package into a virtual environment or Conda environment.
install_sympy(method = "auto", conda = "auto")install_sympy(method = "auto", conda = "auto")
method |
Installation method. By default, "auto" automatically finds a method that will work in the local environment. Change the default to force a specific installation method. Note that the "virtualenv" method is not available on Windows. |
conda |
Path to conda executable (or "auto" to find conda using the PATH and other conventional install locations). |
None
If no limits are provided, the indefinite integral is calculated. Otherwise, if both limits are provided, the definite integral is calculated.
int(f, var, lower, upper, doit = TRUE)int(f, var, lower, upper, doit = TRUE)
f |
Function to integrate |
var |
Variable to integrate with respect to (either string or |
lower |
Lower limit |
upper |
Upper limit |
doit |
Evaluate the integral immediately (or later with |
if (has_sympy()) { x <- symbol("x") int(1/x, x, 1, 10) int(1/x, x, 1, 10, doit = FALSE) int(1/x, x) int(1/x, x, doit = FALSE) int(exp(-x^2/2), x, -Inf, Inf) int(exp(-x^2/2), x, -Inf, Inf, doit = FALSE) }if (has_sympy()) { x <- symbol("x") int(1/x, x, 1, 10) int(1/x, x, 1, 10, doit = FALSE) int(1/x, x) int(1/x, x, doit = FALSE) int(exp(-x^2/2), x, -Inf, Inf) int(exp(-x^2/2), x, -Inf, Inf, doit = FALSE) }
Inverse of block matrix
inv_block(x)inv_block(x)
x |
A block matrix, either a caracas matrix, or a dense or a sparse matrix. |
The inverse in the same form as x.
Søren Højsgaard
if (has_sympy()) { I <- diag_(1, 3) M <- as_sym(matrix(c("a", "b", "c", "d"), nrow=2)) IM <- kronecker(I, M) inv(IM) inv_block(IM) IM. <- subs(IM, c("a", "b", "c", "d"), c(2,1,2,2)) inv_block(IM.) }if (has_sympy()) { I <- diag_(1, 3) M <- as_sym(matrix(c("a", "b", "c", "d"), nrow=2)) IM <- kronecker(I, M) inv(IM) inv_block(IM) IM. <- subs(IM, c("a", "b", "c", "d"), c(2,1,2,2)) inv_block(IM.) }
Computes the inverse of (A + U C V) provided that the inverse of A and C exists.
inv_woodbury(A, U, C, V = t(U), method = "ge", simplify = TRUE)inv_woodbury(A, U, C, V = t(U), method = "ge", simplify = TRUE)
A, U, C, V
|
Either a caracas matrix, or a dense or a sparse matrix. |
method |
One of the methods that can be supplied to inv(). |
simplify |
Should temporary quantities be simplified? |
The inverse of (A + U C V)
Søren Højsgaard
if (has_sympy()) { n <- 8 m <- 4 A <- diag_("a", n) C <- diag_("c", m) set.seed(1234) U <- round(10 * (matrix(rnorm(n * m), nrow=n))) U[U < 0] <- 0 U <- as_sym(U) V <- t(U) B <- A + U %*% C %*% V B system.time(Bi <- inv_woodbury(A, U, C, simplify=FALSE)) }if (has_sympy()) { n <- 8 m <- 4 A <- diag_("a", n) C <- diag_("c", m) set.seed(1234) U <- round(10 * (matrix(rnorm(n * m), nrow=n))) U[U < 0] <- 0 U <- as_sym(U) V <- t(U) B <- A + U %*% C %*% V B system.time(Bi <- inv_woodbury(A, U, C, simplify=FALSE)) }
Is object a caracas symbol
is_sym(x)is_sym(x)
x |
object |
Is list of caracas symbols
is_sym_list(x)is_sym_list(x)
x |
Object |
logical
Søren Højsgaard
Compute Jacobian
jacobian(expr, vars)jacobian(expr, vars)
expr |
'caracas expression'. |
vars |
variables to take derivative with respect to |
if (has_sympy()) { x <- paste0("x", seq_len(3)) def_sym_vec(x) y1 <- x1 + x2 y2 <- x1^2 + x3 y <- c(y1, y2) jacobian(y, x) u <- 2 + 4*x1^2 jacobian(u, x1) }if (has_sympy()) { x <- paste0("x", seq_len(3)) def_sym_vec(x) y1 <- x1 + x2 y2 <- x1^2 + x3 y <- c(y1, y2) jacobian(y, x) u <- 2 + 4*x1^2 jacobian(u, x1) }
Computes the Kronecker product of two matrices.
## S4 method for signature 'caracas_symbol,caracas_symbol' kronecker(X, Y, FUN = "*", make.dimnames = FALSE, ...)## S4 method for signature 'caracas_symbol,caracas_symbol' kronecker(X, Y, FUN = "*", make.dimnames = FALSE, ...)
X, Y
|
matrices as caracas symbols. |
FUN |
a function; it may be a quoted string. |
make.dimnames |
Provide dimnames that are the product of the dimnames of ‘X’ and ‘Y’. NOT IMPLEMENTED |
... |
optional arguments to be passed to ‘FUN’. |
Kronecker product of A and B.
if (has_sympy()) { A <- matrix_sym(2, 2, "a") B <- matrix_sym(2, 2, "b") II <- matrix_sym_diag(2) EE <- eye_sym(2,2) JJ <- ones_sym(2,2) kronecker(A, B) kronecker(A, B, FUN = "+") kronecker(II, B) kronecker(EE, B) kronecker(JJ, B) Y <- matrix_sym(2, 2) X1 <- diag_(1, 3) X2 <- diag_(as_sym(c("a1", "a2", "a3"))) X3 <- matrix_sym(2,2, "u") kronecker(X1, Y) kronecker(X2, Y, FUN="-") kronecker(X3, Y) }if (has_sympy()) { A <- matrix_sym(2, 2, "a") B <- matrix_sym(2, 2, "b") II <- matrix_sym_diag(2) EE <- eye_sym(2,2) JJ <- ones_sym(2,2) kronecker(A, B) kronecker(A, B, FUN = "+") kronecker(II, B) kronecker(EE, B) kronecker(JJ, B) Y <- matrix_sym(2, 2) X1 <- diag_(1, 3) X2 <- diag_(as_sym(c("a1", "a2", "a3"))) X3 <- matrix_sym(2,2, "u") kronecker(X1, Y) kronecker(X2, Y, FUN="-") kronecker(X3, Y) }
Length of (caracas) object
length_(x)length_(x)
x |
an object |
length
Søren Højsgaard
Limit of a function
lim(f, var, val, dir = NULL, doit = TRUE)lim(f, var, val, dir = NULL, doit = TRUE)
f |
Function to take limit of |
var |
Variable to take limit for (either string or |
val |
Value for |
dir |
Direction from where |
doit |
Evaluate the limit immediately (or later with |
if (has_sympy()) { x <- symbol("x") lim(sin(x)/x, "x", 0) lim(1/x, "x", 0, dir = '+') lim(1/x, "x", 0, dir = '-') }if (has_sympy()) { x <- symbol("x") lim(sin(x)/x, "x", 0) lim(1/x, "x", 0, dir = '+') lim(1/x, "x", 0, dir = '-') }
Performs various linear algebra operations like finding the inverse, the QR decomposition, the eigenvectors and the eigenvalues.
columnspace(x, matrix = TRUE) nullspace(x, matrix = TRUE) rowspace(x, matrix = TRUE) orthcompspace(x, x2 = NULL) intersectionspace(x, x2) leftnullspace(x) singular_values(x) inv( x, method = c("ge", "gauss", "lu", "cf", "ch", "qr", "adj", "ldl", "block", "yac") ) eigenval(x) eigenvec(x) eigen_(x) GramSchmidt(x) pinv(x) QRdecomposition(x) ## S4 method for signature 'caracas_symbol' qr(x) ## S4 method for signature 'caracas_symbol' chol(x, ...) ## S4 method for signature 'QRdecomposition' qr.Q(qr) ## S4 method for signature 'QRdecomposition' qr.R(qr) LUdecomposition(x) svd_(x, ...) det(x, ...) det_(x, ...) trace_(x)columnspace(x, matrix = TRUE) nullspace(x, matrix = TRUE) rowspace(x, matrix = TRUE) orthcompspace(x, x2 = NULL) intersectionspace(x, x2) leftnullspace(x) singular_values(x) inv( x, method = c("ge", "gauss", "lu", "cf", "ch", "qr", "adj", "ldl", "block", "yac") ) eigenval(x) eigenvec(x) eigen_(x) GramSchmidt(x) pinv(x) QRdecomposition(x) ## S4 method for signature 'caracas_symbol' qr(x) ## S4 method for signature 'caracas_symbol' chol(x, ...) ## S4 method for signature 'QRdecomposition' qr.Q(qr) ## S4 method for signature 'QRdecomposition' qr.R(qr) LUdecomposition(x) svd_(x, ...) det(x, ...) det_(x, ...) trace_(x)
x, x2
|
A matrix for which a property is requested. |
matrix |
When relevant should a matrix be returned. |
method |
The default works by Gaussian elimination.
Alternatives are $LU$ decomposition ( |
... |
Auxillary arguments. |
qr |
A QRdecomposition object. |
Returns the requested property of a matrix.
if (has_sympy()) { A <- matrix(c("a", "0", "0", "1"), 2, 2) |> as_sym() QRdecomposition(A) LUdecomposition(A) #chol(A) # error chol(A, hermitian = FALSE) eigenval(A) eigenvec(A) inv(A) det(A) rowspace(A) columnspace(A) nullspace(A) ## Matrix inversion: d <- 3 m <- matrix_sym(d, d) print(system.time(inv(m))) ## Gauss elimination print(system.time(inv(m, method="cf"))) ## Cofactor print(system.time(inv(m, method="lu"))) ## LU decomposition if (requireNamespace("Ryacas")){ print(system.time(inv(m, method="yac"))) ## Use Ryacas } A <- matrix(c("a", "b", "c", "d"), 2, 2) |> as_sym() evec <- eigenvec(A) evec evec1 <- evec[[1]]$eigvec evec1 simplify(evec1) lapply(evec, function(l) simplify(l$eigvec)) A <- as_sym("[[1, 2, 3], [4, 5, 6]]") pinv(A) }if (has_sympy()) { A <- matrix(c("a", "0", "0", "1"), 2, 2) |> as_sym() QRdecomposition(A) LUdecomposition(A) #chol(A) # error chol(A, hermitian = FALSE) eigenval(A) eigenvec(A) inv(A) det(A) rowspace(A) columnspace(A) nullspace(A) ## Matrix inversion: d <- 3 m <- matrix_sym(d, d) print(system.time(inv(m))) ## Gauss elimination print(system.time(inv(m, method="cf"))) ## Cofactor print(system.time(inv(m, method="lu"))) ## LU decomposition if (requireNamespace("Ryacas")){ print(system.time(inv(m, method="yac"))) ## Use Ryacas } A <- matrix(c("a", "b", "c", "d"), 2, 2) |> as_sym() evec <- eigenvec(A) evec evec1 <- evec[[1]]$eigvec evec1 simplify(evec1) lapply(evec, function(l) simplify(l$eigvec)) A <- as_sym("[[1, 2, 3], [4, 5, 6]]") pinv(A) }
Finds the basis of the (right) null space of a matrix, a vector (a 1-column matrix) or a model object for which a model matrix can be extracted. I.e. finds basis for the (right) null space x : Mx = 0.
is_caracas_matrix(M) basis_intersect(M, M2) basis_orthcomp(M, M2 = NULL) basis_col(M) basis_row(M) basis_null(M) basis_leftnull(M) rref(M)is_caracas_matrix(M) basis_intersect(M, M2) basis_orthcomp(M, M2 = NULL) basis_col(M) basis_row(M) basis_null(M) basis_leftnull(M) rref(M)
M, M2
|
A matrix or a vector (a 1-column matrix). |
A matrix (possibly with zero columns if the null space consists only of the zero vector).
Søren Højsgaard, [email protected]
M <- matrix(c(1,1,1,1,1,1,0,0,0,0,1,1), nrow=4) basis_null(M) MASS::Null(t(M)) M <- matrix(c(1,1,1,1)) basis_null(M) MASS::Null(t(M)) m0 <- lm(breaks ~ wool + tension, data=warpbreaks) basis_null(model.matrix(m0)) MASS::Null(t(model.matrix(m0))) ## Make balanced dataset dat.bal <- expand.grid(list(A=factor(1:2), B=factor(1:3), C=factor(1:3))) dat.bal$y <- rnorm(nrow(dat.bal)) ## Make unbalanced dataset: 'B' is nested within 'C' so B=1 is only ## found when C=1 and B=2,3 are found in each C=2,3,4 dat.nst <- dat.bal dat.nst$C <-factor(c(1,1,2,2,2,2,1,1,3,3,3,3,1,1,4,4,4,4)) xtabs(y ~ C+B+A , data=dat.nst) mod.bal <- lm(y ~ A + B*C, data=dat.bal) mod.nst <- lm(y ~ A + B*C, data=dat.nst) basis_null( model.matrix(mod.bal) ) basis_null( model.matrix(mod.nst) ) MASS::Null( t(model.matrix(mod.bal)) ) MASS::Null( t(model.matrix(mod.nst)) )M <- matrix(c(1,1,1,1,1,1,0,0,0,0,1,1), nrow=4) basis_null(M) MASS::Null(t(M)) M <- matrix(c(1,1,1,1)) basis_null(M) MASS::Null(t(M)) m0 <- lm(breaks ~ wool + tension, data=warpbreaks) basis_null(model.matrix(m0)) MASS::Null(t(model.matrix(m0))) ## Make balanced dataset dat.bal <- expand.grid(list(A=factor(1:2), B=factor(1:3), C=factor(1:3))) dat.bal$y <- rnorm(nrow(dat.bal)) ## Make unbalanced dataset: 'B' is nested within 'C' so B=1 is only ## found when C=1 and B=2,3 are found in each C=2,3,4 dat.nst <- dat.bal dat.nst$C <-factor(c(1,1,2,2,2,2,1,1,3,3,3,3,1,1,4,4,4,4)) xtabs(y ~ C+B+A , data=dat.nst) mod.bal <- lm(y ~ A + B*C, data=dat.bal) mod.nst <- lm(y ~ A + B*C, data=dat.nst) basis_null( model.matrix(mod.bal) ) basis_null( model.matrix(mod.nst) ) MASS::Null( t(model.matrix(mod.bal)) ) MASS::Null( t(model.matrix(mod.nst)) )
Convert object to list of elements
listify(x)listify(x)
x |
Object |
if (has_sympy()) { x <- as_sym("Matrix([[b1*x1/(b2 + x1)], [b1*x2/(b2 + x2)], [b1*x3/(b2 + x3)]])") listify(x) xT <- t(x) listify(xT) def_sym(s) listify(s) listify(c_(s, s)) }if (has_sympy()) { x <- as_sym("Matrix([[b1*x1/(b2 + x1)], [b1*x2/(b2 + x2)], [b1*x3/(b2 + x3)]])") listify(x) xT <- t(x) listify(xT) def_sym(s) listify(s) listify(c_(s, s)) }
Matrix power
mat_pow(x, pow = "1")mat_pow(x, pow = "1")
x |
A |
pow |
Power to raise matrix |
if (has_sympy() && sympy_version() >= "1.6") { M <- matrix_(c("1", "a", "a", 1), 2, 2) M mat_pow(M, 1/2) }if (has_sympy() && sympy_version() >= "1.6") { M <- matrix_(c("1", "a", "a", 1), 2, 2) M mat_pow(M, 1/2) }
If x is a matrix, the function is applied component-wise.
## S3 method for class 'caracas_symbol' Math(x, ...)## S3 method for class 'caracas_symbol' Math(x, ...)
x |
|
... |
further arguments passed to methods |
Creates matrix from array symbol
matrify(x)matrify(x)
x |
Array symbol to convert to matrix |
if (has_sympy()) { x <- symbol("x") y <- symbol("y") f <- 3*x^2 + x*y^2 matrify(f) h <- der2(f, list(x, y)) h dim(h) H <- matrify(h) H dim(H) }if (has_sympy()) { x <- symbol("x") y <- symbol("y") f <- 3*x^2 + x*y^2 matrify(f) h <- der2(f, list(x, y)) h dim(h) H <- matrify(h) H dim(H) }
Symbolic matrix
matrix_(..., declare_symbols = TRUE)matrix_(..., declare_symbols = TRUE)
... |
Passed on to |
declare_symbols |
Passed on to |
if (has_sympy()) { matrix_(1:9, nrow = 3) matrix_("a", 2, 2) }if (has_sympy()) { matrix_(1:9, nrow = 3) matrix_("a", 2, 2) }
Matrix cross product
crossprod_(x, y = NULL) tcrossprod_(x, y = NULL) ## S4 method for signature 'caracas_symbol,missing' crossprod(x, y) ## S4 method for signature 'caracas_symbol,missing' tcrossprod(x, y)crossprod_(x, y = NULL) tcrossprod_(x, y = NULL) ## S4 method for signature 'caracas_symbol,missing' crossprod(x, y) ## S4 method for signature 'caracas_symbol,missing' tcrossprod(x, y)
x, y
|
caracas matrices |
if (has_sympy()) { s <- as_sym("[[r1, r2, r3], [u1, u2, u3]]") s2 <- apply(as_character_matrix(s), 2, function(x) (paste("1/(", x, ")"))) as_sym(s2) }if (has_sympy()) { s <- as_sym("[[r1, r2, r3], [u1, u2, u3]]") s2 <- apply(as_character_matrix(s), 2, function(x) (paste("1/(", x, ")"))) as_sym(s2) }
Matrix multiplication
Matrix multiplication
x %*% y ## S3 method for class 'caracas_symbol' x %*% yx %*% y ## S3 method for class 'caracas_symbol' x %*% y
x |
Object |
y |
Object |
Numerical evaluation
N(x, digits = 15)N(x, digits = 15)
x |
caracas object |
digits |
Number of digits |
if (has_sympy()) { n_2 <- as_sym("2") n_pi <- as_sym("pi", declare_symbols = FALSE) x <- sqrt(n_2) * n_pi x N(x) N(x, 5) N(x, 50) as.character(N(x, 50)) }if (has_sympy()) { n_2 <- as_sym("2") n_pi <- as_sym("pi", declare_symbols = FALSE) x <- sqrt(n_2) * n_pi x N(x) N(x, 5) N(x, 50) as.character(N(x, 50)) }
Math operators
## S3 method for class 'caracas_symbol' Ops(e1, e2)## S3 method for class 'caracas_symbol' Ops(e1, e2)
e1 |
A |
e2 |
A |
Adaptation of optim() to work on caracas symbols.
optim_sym( par, fn, gr = NULL, ..., method = c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN", "Brent"), lower = -Inf, upper = Inf, control = list(), hessian = FALSE )optim_sym( par, fn, gr = NULL, ..., method = c("Nelder-Mead", "BFGS", "CG", "L-BFGS-B", "SANN", "Brent"), lower = -Inf, upper = Inf, control = list(), hessian = FALSE )
par |
As for optim() |
fn |
A caracas symbol |
gr |
As for optim() |
... |
As for optim() |
method |
As for optim() |
lower |
As for optim() |
upper |
As for optim() |
control |
As for optim() |
hessian |
As for optim() |
The caracas symbol fn is coerced into an R function on which optim() is subsequently applied.
As for optim()
Søren Højsgaard
Create a piecewise object
Extract or replace parts of an object
as_piecewise(pw) piecewise_cond(pw) piecewise_expr(pw) ## S3 method for class 'caracas_piecewise' x[i, j, ..., drop = TRUE]as_piecewise(pw) piecewise_cond(pw) piecewise_expr(pw) ## S3 method for class 'caracas_piecewise' x[i, j, ..., drop = TRUE]
pw |
A caracas object containg a Piecewise specification |
x |
A |
i |
row indices specifying elements to extract or replace |
j |
column indices specifying elements to extract or replace |
... |
Not used |
drop |
Simplify dimensions of resulting object |
A list
Søren Højsgaard
if (has_sympy()) { library(caracas) def_sym(r, n, j) sum1 <- sum_(r^j, var=j, lower=0, upper=n) pw <- as_piecewise(sum1) pw[[2]]$expr pw |> piecewise_cond() pw |> piecewise_expr() }if (has_sympy()) { library(caracas) def_sym(r, n, j) sum1 <- sum_(r^j, var=j, lower=0, upper=n) pw <- as_piecewise(sum1) pw[[2]]$expr pw |> piecewise_cond() pw |> piecewise_expr() }
Print scaled matrix
## S3 method for class 'caracas_scaled_matrix' print(x, ...)## S3 method for class 'caracas_scaled_matrix' print(x, ...)
x |
A |
... |
Passed to |
Print solution
## S3 method for class 'caracas_solve_sys_sol' print( x, simplify = getOption("caracas.print.sol.simplify", default = TRUE), ... )## S3 method for class 'caracas_solve_sys_sol' print( x, simplify = getOption("caracas.print.sol.simplify", default = TRUE), ... )
x |
A |
simplify |
Print solution in a simple format |
... |
Passed to |
if (has_sympy()) { x <- symbol('x') solve_sys(x^2, -1, x) y <- symbol("y") lhs <- cbind(3*x*y - y, x) rhs <- cbind(-5*x, y+4) sol <- solve_sys(lhs, rhs, list(x, y)) sol }if (has_sympy()) { x <- symbol('x') solve_sys(x^2, -1, x) y <- symbol("y") lhs <- cbind(3*x*y - y, x) rhs <- cbind(-5*x, y+4) sol <- solve_sys(lhs, rhs, list(x, y)) sol }
Print symbol
## S3 method for class 'caracas_symbol' print( x, prompt = getOption("caracas.prompt", default = "c: "), method = getOption("caracas.print.method", default = "utf8"), rowvec = getOption("caracas.print.rowvec", default = TRUE), ... )## S3 method for class 'caracas_symbol' print( x, prompt = getOption("caracas.prompt", default = "c: "), method = getOption("caracas.print.method", default = "utf8"), rowvec = getOption("caracas.print.rowvec", default = TRUE), ... )
x |
A |
prompt |
Which prompt/prefix to print (default: 'c: ') |
method |
What way to print ( |
rowvec |
|
... |
not used |
Product of a function
prod_(f, var, lower, upper, doit = TRUE)prod_(f, var, lower, upper, doit = TRUE)
f |
Function to take product of |
var |
Variable to take product for (either string or |
lower |
Lower limit |
upper |
Upper limit |
doit |
Evaluate the product immediately (or later with |
if (has_sympy()) { 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) }if (has_sympy()) { 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) }
Rank of symbolic or numeric matrix.
rankMatrix_(x, tol = NULL)rankMatrix_(x, tol = NULL)
x |
Numeric or symbolic matrix. |
tol |
Tolerence, only relevant for a numeric matrix. |
if (has_sympy()) { X <- matrix_(paste0("x_",c(1,1,1,1,2,2,2,2,3,4,3,4)), nrow=4) X rankMatrix_(X) colspan(X) }if (has_sympy()) { X <- matrix_(paste0("x_",c(1,1,1,1,2,2,2,2,3,4,3,4)), nrow=4) X rankMatrix_(X) colspan(X) }
Refresh as symbol
re_sym(x)re_sym(x)
x |
caracas symbol |
caracas symbol
if (has_sympy()) { x <- symbol('x', positive=TRUE) e <- 2*x^2 ## Substitute 2 for x subs(e, "x", 2) ## Fails because of restriction that x is positive ## Refresh symbol e <- re_sym(e) ## Works subs(e, "x", "2") ## OK }if (has_sympy()) { x <- symbol('x', positive=TRUE) e <- 2*x^2 ## Substitute 2 for x subs(e, "x", 2) ## Fails because of restriction that x is positive ## Refresh symbol e <- re_sym(e) ## Works subs(e, "x", "2") ## OK }
Elementwise reciprocal matrix
reciprocal_matrix(x, numerator = 1)reciprocal_matrix(x, numerator = 1)
x |
Object |
numerator |
The numerator in the result. |
if (has_sympy()) { s <- as_sym("[[r1, r2, r3], [u1, u2, u3]]") reciprocal_matrix(s, numerator = 7) }if (has_sympy()) { s <- as_sym("[[r1, r2, r3], [u1, u2, u3]]") reciprocal_matrix(s, numerator = 7) }
Form Row and Column Sums
rowSums_(x) colSums_(x)rowSums_(x) colSums_(x)
x |
Symbolic matrix |
if (has_sympy()) { X <- matrix_(paste0("x_",c(1,1,1,1,2,2,2,2,3,4,3,4)), nrow=4) rowSums_(X) colSums_(X) }if (has_sympy()) { X <- matrix_(paste0("x_",c(1,1,1,1,2,2,2,2,3,4,3,4)), nrow=4) rowSums_(X) colSums_(X) }
Create list of factors as in a product
scale_matrix(X, k = NULL, divide = TRUE)scale_matrix(X, k = NULL, divide = TRUE)
X |
matrix |
k |
scalar to be factored out |
divide |
Should |
if (has_sympy()) { V <- matrix_sym(2, 2, "v") a <- symbol("a") K <- a*V scale_matrix(K, a) scale_matrix(V, a, divide = FALSE) Ks <- scale_matrix(V, a, divide = FALSE) Ks W <- matrix_sym(2, 2, "w") unscale_matrix(Ks) %*% W unscale_matrix(Ks) %*% W |> scale_matrix(a) Ksi <- unscale_matrix(Ks) |> inv() |> scale_matrix(a/det(unscale_matrix(Ks))) (Ksi |> unscale_matrix()) %*% (Ks |> unscale_matrix()) |> simplify() tex(Ksi) }if (has_sympy()) { V <- matrix_sym(2, 2, "v") a <- symbol("a") K <- a*V scale_matrix(K, a) scale_matrix(V, a, divide = FALSE) Ks <- scale_matrix(V, a, divide = FALSE) Ks W <- matrix_sym(2, 2, "w") unscale_matrix(Ks) %*% W unscale_matrix(Ks) %*% W |> scale_matrix(a) Ksi <- unscale_matrix(Ks) |> inv() |> scale_matrix(a/det(unscale_matrix(Ks))) (Ksi |> unscale_matrix()) %*% (Ks |> unscale_matrix()) |> simplify() tex(Ksi) }
Compute column vector of first derivatives and matrix of second derivatives of univariate function.
score(expr, vars, simplify = TRUE) hessian(expr, vars, simplify = TRUE)score(expr, vars, simplify = TRUE) hessian(expr, vars, simplify = TRUE)
expr |
'caracas expression'. |
vars |
variables to take derivative with respect to. |
simplify |
Try to simplify result using |
if (has_sympy()) { def_sym(b0, b1, x, x0) f <- b0 / (1 + exp(b1*(x-x0))) S <- score(f, c(b0, b1)) S H <- hessian(f, c(b0, b1)) H }if (has_sympy()) { def_sym(b0, b1, x, x0) f <- b0 / (1 + exp(b1*(x-x0))) S <- score(f, c(b0, b1)) S H <- hessian(f, c(b0, b1)) H }
Simplify expression
Expand expression
simplify(x) ## S4 method for signature 'caracas_symbol' expand(x, ...)simplify(x) ## S4 method for signature 'caracas_symbol' expand(x, ...)
x |
A |
... |
Pass on to SymPy's expand, e.g. |
if (has_sympy()) { def_sym(x) y <- log(exp(x)) simplify(y) expand(simplify(y)) expand(simplify(y), force = TRUE) expand_log(simplify(y)) }if (has_sympy()) { def_sym(x) y <- log(exp(x)) simplify(y) expand(simplify(y)) expand(simplify(y), force = TRUE) expand_log(simplify(y)) }
Find x in Ax = b. If b not supplied,
the inverse of A is returned.
solve_lin(A, b)solve_lin(A, b)
A |
matrix |
b |
vector |
if (has_sympy()) { A <- matrix_sym(2, 2, "a") b <- vector_sym(2, "b") # Inverse of A: solve_lin(A) %*% A |> simplify() # Find x in Ax = b x <- solve_lin(A, b) A %*% x |> simplify() }if (has_sympy()) { A <- matrix_sym(2, 2, "a") b <- vector_sym(2, "b") # Inverse of A: solve_lin(A) %*% A |> simplify() # Find x in Ax = b x <- solve_lin(A, b) A %*% x |> simplify() }
If called as solve_sys(lhs, vars)
the roots are found.
If called as solve_sys(lhs, rhs, vars)
the solutions to lhs = rhs for vars are found.
solve_sys(lhs, rhs, vars)solve_sys(lhs, rhs, vars)
lhs |
Equation (or equations as row vector/1xn matrix) |
rhs |
Equation (or equations as row vector/1xn matrix) |
vars |
vector of variable names or symbols |
A list with solutions (with class caracas_solve_sys_sol
for compact printing), each element containing a named
list of the variables' values.
if (has_sympy()) { x <- symbol('x') exp1 <- 2*x + 2 exp2 <- x solve_sys(cbind(exp1), cbind(exp2), x) x <- symbol("x") y <- symbol("y") lhs <- cbind(3*x*y - y, x) rhs <- cbind(-5*x, y+4) sol <- solve_sys(lhs, rhs, list(x, y)) sol }if (has_sympy()) { x <- symbol('x') exp1 <- 2*x + 2 exp2 <- x solve_sys(cbind(exp1), cbind(exp2), x) x <- symbol("x") y <- symbol("y") lhs <- cbind(3*x*y - y, x) rhs <- cbind(-5*x, y+4) sol <- solve_sys(lhs, rhs, list(x, y)) sol }
Solve lower or upper triangular system
solve_lower_triangular(a, b, ...) solve_upper_triangular(a, b, ...)solve_lower_triangular(a, b, ...) solve_upper_triangular(a, b, ...)
a |
caracas_symbol |
b |
If provided, either a caracas_symbol (if not, |
... |
Not used |
if (has_sympy()) { A <- matrix_sym(3, 3) A[upper.tri(A)] <- 0 solve_lower_triangular(A) |> simplify() A <- matrix_sym(3, 3) A[lower.tri(A)] <- 0 solve_upper_triangular(A) |> simplify() }if (has_sympy()) { A <- matrix_sym(3, 3) A[upper.tri(A)] <- 0 solve_lower_triangular(A) |> simplify() A <- matrix_sym(3, 3) A[lower.tri(A)] <- 0 solve_upper_triangular(A) |> simplify() }
Solve a System of Linear Equations
## S3 method for class 'caracas_symbol' solve( a, b, method = c("ge", "gauss", "lu", "cf", "qr", "adj", "ldl", "block", "yac"), ... )## S3 method for class 'caracas_symbol' solve( a, b, method = c("ge", "gauss", "lu", "cf", "qr", "adj", "ldl", "block", "yac"), ... )
a |
caracas_symbol |
b |
If provided, either a caracas_symbol (if not, |
method |
See available methods for inv() |
... |
Not used |
if (has_sympy()) { A <- matrix_sym(2, 2, "a") b <- vector_sym(2, "b") # Inverse of A: solve(A) inv(A) solve(A) %*% A |> simplify() # Find x in Ax = b x <- solve(A, b) A %*% x |> simplify() solve(A, c(2, 1)) |> simplify() }if (has_sympy()) { A <- matrix_sym(2, 2, "a") b <- vector_sym(2, "b") # Inverse of A: solve(A) inv(A) solve(A) %*% A |> simplify() # Find x in Ax = b x <- solve(A, b) A %*% x |> simplify() solve(A, c(2, 1)) |> simplify() }
Special matrices: zeros_sym, ones_sym, eye_sym
zeros_sym(nrow, ncol) ones_sym(nrow, ncol) eye_sym(nrow, ncol)zeros_sym(nrow, ncol) ones_sym(nrow, ncol) eye_sym(nrow, ncol)
nrow, ncol
|
Number of rows and columns of output |
diag_(), matrix_sym(), vector_sym()
if (has_sympy()){ zeros_sym(3, 4) ones_sym(3, 4) eye_sym(3, 4) }if (has_sympy()){ zeros_sym(3, 4) ones_sym(3, 4) eye_sym(3, 4) }
Utilities for computing symbolic (or numeric) sums of matrix entries for common structured matrices, without explicitly constructing the full matrix.
toeplitz_sum()Sum of entries in a banded symmetric Toeplitz matrix
with diagonal values given by r = (r0, r1, r2, ...).
ar1_sum()Sum of entries in an AR(1) correlation
matrix .
har1_sum()Sum of entries in a heterogeneous AR(1) covariance matrix
where and
, i.e. .
This is returned expanded in terms of the provided vector.
toeplitz_sum(n, r, upper = FALSE, diag = TRUE) ar1_sum(n, rho, upper = FALSE, diag = TRUE) har1_sum(rho, sigma)toeplitz_sum(n, r, upper = FALSE, diag = TRUE) ar1_sum(n, rho, upper = FALSE, diag = TRUE) har1_sum(rho, sigma)
n |
Integer (or symbolic) matrix dimension for |
r |
A caracas symbolic vector (or numeric vector) |
upper |
Logical; if |
diag |
Logical; include the diagonal contribution if |
rho |
AR(1) parameter (symbolic or numeric). |
sigma |
A caracas symbolic vector (or numeric vector) |
A caracas symbolic expression (typically a scalar), or a numeric value if inputs are numeric.
if (has_sympy()) { ## Toeplitz: sum of all entries in an n x n banded Toeplitz matrix def_sym(n, r0, r1, r2) r <- c(r0, r1, r2) # diagonals: r0 on main, r1 on first, r2 on second toeplitz_sum(n, r) toeplitz_sum(n, r, upper = TRUE, diag = FALSE) # strictly upper triangular sum ## AR(1) correlation: R_ij = rho^|i-j| def_sym(n, rho) ar1_sum(n, rho) ar1_sum(n, rho, upper = TRUE, diag = FALSE) ## Heterogeneous AR(1): Sigma = diag(sigma) %*% AR1 %*% diag(sigma) def_sym(rho, sigma_1, sigma_2, sigma_3, sigma_4) sigma <- c(sigma_1, sigma_2, sigma_3, sigma_4) simplify(har1_sum(rho, sigma)) ## Numeric check (small n) ar1_sum(5, 0.2) }if (has_sympy()) { ## Toeplitz: sum of all entries in an n x n banded Toeplitz matrix def_sym(n, r0, r1, r2) r <- c(r0, r1, r2) # diagonals: r0 on main, r1 on first, r2 on second toeplitz_sum(n, r) toeplitz_sum(n, r, upper = TRUE, diag = FALSE) # strictly upper triangular sum ## AR(1) correlation: R_ij = rho^|i-j| def_sym(n, rho) ar1_sum(n, rho) ar1_sum(n, rho, upper = TRUE, diag = FALSE) ## Heterogeneous AR(1): Sigma = diag(sigma) %*% AR1 %*% diag(sigma) def_sym(rho, sigma_1, sigma_2, sigma_3, sigma_4) sigma <- c(sigma_1, sigma_2, sigma_3, sigma_4) simplify(har1_sum(rho, sigma)) ## Numeric check (small n) ar1_sum(5, 0.2) }
Perform symbolic substitution in a caracas_symbol object.
subs(sym, nms, vls)subs(sym, nms, vls)
sym |
A |
nms |
Symbols to replace. Either:
|
vls |
Replacement values (only used when |
Two calling styles are supported:
Mapping as a named list: Supply nms as a named list and omit vls.
Names are the symbols to be replaced; list elements are the replacement values.
Parallel vectors: Supply both nms and vls of the same length.
Replacements may be numbers, character strings, caracas_symbol objects,
or other objects that caracas can convert to SymPy.
If the same symbol is provided more than once, the result depends on evaluation order in the backend and should be considered undefined.
A caracas_symbol object with substitutions applied.
if (has_sympy()) { x <- symbol("x") e <- 2*x^2 e subs(e, "x", "2") subs(e, x, 2) subs(e, list(x = 2)) A <- matrix_sym(2, 2, "a") B <- matrix_sym(2, 2, "b") e2 <- A %*% A subs(e2, A, B) }if (has_sympy()) { x <- symbol("x") e <- 2*x^2 e subs(e, "x", "2") subs(e, x, 2) subs(e, list(x = 2)) A <- matrix_sym(2, 2, "a") B <- matrix_sym(2, 2, "b") e2 <- A %*% A subs(e2, A, B) }
Convenience wrapper for symbolic substitution in caracas_symbol objects.
subs_expr(sym, old, new)subs_expr(sym, old, new)
sym |
A |
old |
Symbols to replace (character or |
new |
Replacement value(s) corresponding to |
A caracas_symbol object with substitutions applied.
if (has_sympy()) { x <- symbol("x"); y <- symbol("y") e <- (x + 1)^2 + y # Named arguments: subs_expr(e, x = 2) # Named list: subs_expr(e, list(x = 2, y = 10)) # Works with matrices too: A <- matrix_sym(2, 2, "a") B <- matrix_sym(2, 2, "b") subs_expr(A %*% A, A = B) }if (has_sympy()) { x <- symbol("x"); y <- symbol("y") e <- (x + 1)^2 + y # Named arguments: subs_expr(e, x = 2) # Named list: subs_expr(e, list(x = 2, y = 10)) # Works with matrices too: A <- matrix_sym(2, 2, "a") B <- matrix_sym(2, 2, "b") subs_expr(A %*% A, A = B) }
Substitute symbol for value
subs_list(sym_list, nms_list, vls_list)subs_list(sym_list, nms_list, vls_list)
sym_list |
Expression |
nms_list |
Names of symbols (see Details) |
vls_list |
Values that |
Sum of a function
sum_(f, var, lower, upper, doit = TRUE)sum_(f, var, lower, upper, doit = TRUE)
f |
Function to take sum of |
var |
Variable to take sum for (either string or |
lower |
Lower limit |
upper |
Upper limit |
doit |
Evaluate the sum immediately (or later with |
if (has_sympy()) { x <- symbol("x") s <- sum_(1/x, "x", 1, 10) as_expr(s) sum(1/(1:10)) n <- symbol("n") simplify(sum_(x, x, 1, n)) }if (has_sympy()) { x <- symbol("x") s <- sum_(1/x, "x", 1, 10) as_expr(s) sum(1/(1:10)) n <- symbol("n") simplify(sum_(x, x, 1, n)) }
Summation
## S3 method for class 'caracas_symbol' sum(..., na.rm = FALSE)## S3 method for class 'caracas_symbol' sum(..., na.rm = FALSE)
... |
Elements to sum |
na.rm |
Not used |
Ask type of caracas symbol
sym_class(x)sym_class(x)
x |
An object, a caracas object is expected |
Ask if type of caracas symbol is of a requested type
sym_inherits(x, what)sym_inherits(x, what)
x |
An object, a caracas object is expected |
what |
Requested type (e.g. atomic, vector, list, matrix) |
Find available assumptions at https://docs.sympy.org/latest/modules/core.html#module-sympy.core.assumptions.
symbol(x, ...)symbol(x, ...)
x |
Name to turn into symbol |
... |
Assumptions like |
A caracas_symbol
if (has_sympy()) { x <- symbol("x") 2*x x <- symbol("x", positive = TRUE) ask(x, "positive") }if (has_sympy()) { x <- symbol("x") 2*x x <- symbol("x", positive = TRUE) ask(x, "positive") }
Ask type of caracas symbol
symbol_class(x)symbol_class(x)
x |
An object, a caracas object is expected |
Check if object is a caracas matrix
symbol_is_matrix(x)symbol_is_matrix(x)
x |
An object |
if (has_sympy() && sympy_version() >= "1.6") { x <- vector_sym(4) symbol_is_matrix(x) ## TRUE x2 <- as.character(x) ## "Matrix([[v1], [v2], [v3], [v4]])" symbol_is_matrix(x2) ## TRUE x3 <- as_character_matrix(x) ## R matrix symbol_is_matrix(x3) ## FALSE }if (has_sympy() && sympy_version() >= "1.6") { x <- vector_sym(4) symbol_is_matrix(x) ## TRUE x2 <- as.character(x) ## "Matrix([[v1], [v2], [v3], [v4]])" symbol_is_matrix(x2) ## TRUE x3 <- as_character_matrix(x) ## R matrix symbol_is_matrix(x3) ## FALSE }
Extend caracas by calling SymPy functions directly.
sympy_func(x, fun, ...)sympy_func(x, fun, ...)
x |
Object to call |
fun |
Function to call |
... |
Passed on to |
if (has_sympy()) { def_sym(x, a) p <- (x-a)^4 p q <- p |> sympy_func("expand") q q |> sympy_func("factor") def_sym(x, y, z) expr <- x*y + x - 3 + 2*x^2 - z*x^2 + x^3 expr expr |> sympy_func("collect", x) x <- symbol("x") y <- gamma(x+3) sympy_func(y, "expand_func") expand_func(y) }if (has_sympy()) { def_sym(x, a) p <- (x-a)^4 p q <- p |> sympy_func("expand") q q |> sympy_func("factor") def_sym(x, y, z) expr <- x*y + x - 3 + 2*x^2 - z*x^2 + x^3 expr expr |> sympy_func("collect", x) x <- symbol("x") y <- gamma(x+3) sympy_func(y, "expand_func") expand_func(y) }
Get 'SymPy' version
sympy_version()sympy_version()
The version of the 'SymPy' available
if (has_sympy()) { sympy_version() }if (has_sympy()) { sympy_version() }
Transpose of matrix
## S3 method for class 'caracas_symbol' t(x)## S3 method for class 'caracas_symbol' t(x)
x |
If |
Taylor expansion
taylor(f, x0 = 0, n = 6)taylor(f, x0 = 0, n = 6)
f |
Function to be expanded |
x0 |
Point to expand around |
n |
Order of remainder term |
if (has_sympy()) { 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() }if (has_sympy()) { 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() }
Export object to TeX
tex(x, zero_as_dot = FALSE, matstr = NULL, ...)tex(x, zero_as_dot = FALSE, matstr = NULL, ...)
x |
A |
zero_as_dot |
Print zero as dots |
matstr |
Replace |
... |
Other arguments passed along |
if (has_sympy()) { S <- matrix_sym_symmetric(3, "s") S[1, 2] <- "1-x" S tex(S) tex(S, matstr = "pmatrix") tex(S, matstr = c("pmatrix", "r")) }if (has_sympy()) { S <- matrix_sym_symmetric(3, "s") S[1, 2] <- "1-x" S tex(S) tex(S, matstr = "pmatrix") tex(S, matstr = c("pmatrix", "r")) }
Export caracas objects to TeX
tex_align
tex_eq
tex_list(..., x = NULL, zero_as_dot = FALSE, matstr = NULL) tex_align(x, zero_as_dot = FALSE, nonumber = TRUE) tex_eq(x, zero_as_dot = FALSE)tex_list(..., x = NULL, zero_as_dot = FALSE, matstr = NULL) tex_align(x, zero_as_dot = FALSE, nonumber = TRUE) tex_eq(x, zero_as_dot = FALSE)
... |
Objects to be put in tex for. Can be |
x |
caracas symbol |
zero_as_dot |
Print zero as dots |
matstr |
Replace |
nonumber |
If |
latex string
latex string
Søren Højsgaard
if (has_sympy()) { X <- matrix_sym(4, 2, "a") b <- vector_sym(2, "b") y <- vector_sym(4, "y") tex(X) tex_list("X=", X) tex_list(y, "=", X, b) tex_list(x=list(y, "=", X, b)) tex_eq(X) tex_align(list(list("X", X))) tex_align(list(list("X", X), list("b", b))) M <- iris[1:3, 1:2] tex_list(M, "+", M, "=", M + M) tex_list(x=list(M, "+", M, "=", M + M)) }if (has_sympy()) { X <- matrix_sym(4, 2, "a") b <- vector_sym(2, "b") y <- vector_sym(4, "y") tex(X) tex_list("X=", X) tex_list(y, "=", X, b) tex_list(x=list(y, "=", X, b)) tex_eq(X) tex_align(list(list("X", X))) tex_align(list(list("X", X), list("b", b))) M <- iris[1:3, 1:2] tex_list(M, "+", M, "=", M + M) tex_list(x=list(M, "+", M, "=", M + M)) }
Export scaled matrix to tex
## S3 method for class 'caracas_scaled_matrix' tex(x, ...)## S3 method for class 'caracas_scaled_matrix' tex(x, ...)
x |
scaled matrix |
... |
Other arguments passed along |
Dump latex representation of sympy object and compile document into pdf.
texshow(x)texshow(x)
x |
An object that can be put in latex format with caracas' tex() function or a character string with tex code (in math mode). |
Nothing, but a .tex file and a .pdf file is generated.
if (has_sympy()) { S <- matrix_sym_symmetric(3, "s") S ## Not run: texshow(S) texshow(paste0("S = ", tex(S))) ## End(Not run) }if (has_sympy()) { S <- matrix_sym_symmetric(3, "s") S ## Not run: texshow(S) texshow(paste0("S = ", tex(S))) ## End(Not run) }
Coerce caracas object
to_list(x) to_vector(x) to_matrix(x)to_list(x) to_vector(x) to_matrix(x)
x |
a caracas object is expected |
Topelitz matrix as caracas matrix.
toeplitz_(x, ...)toeplitz_(x, ...)
x |
The first row of a toeplitz matrix |
... |
Additional arguments passed on to toeplitz |
Convert object to tuple
tuplify(x)tuplify(x)
x |
Object |
if (has_sympy()) { x <- as_sym("Matrix([[b1*x1/(b2 + x1)], [b1*x2/(b2 + x2)], [b1*x3/(b2 + x3)]])") tuplify(x) }if (has_sympy()) { x <- as_sym("Matrix([[b1*x1/(b2 + x1)], [b1*x2/(b2 + x2)], [b1*x3/(b2 + x3)]])") tuplify(x) }
Remove inner-most dimension
unbracket(x)unbracket(x)
x |
Array symbol to collapse dimension from |
if (has_sympy()) { x <- as_sym(paste0("x", 1:3)) y <- as_sym("y") l <- list(x, y) l unbracket(l) }if (has_sympy()) { x <- as_sym(paste0("x", 1:3)) y <- as_sym("y") l <- list(x, y) l unbracket(l) }
a caracas object is returned
c_(...) rep_(...) seq_(...)c_(...) rep_(...) seq_(...)
... |
Arguments to be passed on |
Extract unique elements
## S3 method for class 'caracas_symbol' unique(x, incomparables = FALSE, ...)## S3 method for class 'caracas_symbol' unique(x, incomparables = FALSE, ...)
x |
A caracas vector or matrix |
incomparables |
Same meaning as for other unique methods |
... |
Additional arguments; currently not used. |
if (has_sympy()){ v <- vector_sym(4) v2 <- rep(v, each=2) unique(v2) }if (has_sympy()){ v <- vector_sym(4) v2 <- rep(v, each=2) unique(v2) }
Extract matrix from scaled matrix
unscale_matrix(X)unscale_matrix(X)
X |
scaled matrix created with |
if (has_sympy()) { V <- matrix_sym(2, 2, "v") a <- symbol("a") Ks <- scale_matrix(V, a, divide = FALSE) Ks unscale_matrix(Ks) V %*% a }if (has_sympy()) { V <- matrix_sym(2, 2, "v") a <- symbol("a") Ks <- scale_matrix(V, a, divide = FALSE) Ks unscale_matrix(Ks) V %*% a }
Create a vector along
vec_along(x, entry = "v")vec_along(x, entry = "v")
x |
a caracas object |
entry |
value |
a caracas vector
Søren Højsgaard
Creates symbol vector from list of caracas symbols
vectorfy(x)vectorfy(x)
x |
Symbol to be coerced to vector |