library(caracas)
options("caracas.print.prettyascii"=FALSE)
options("caracas.print.ascii"=TRUE)

It is relatively easy to extend caracas by calling SymPy functions directly.

This can be achived using sympy_func(x, fun, ...) that calls a member function on the object provided, i.e. x$fun(...), or if that fails it calls a function from the global namespace fun(x, ...).

As an example consider inverting a regular matrix \(A\): Let \(B\) be the inverse of \(A\). Then, using cofactors, \(B_{ij} =C_{ji} / det(A)\). The cofactor \(C_{ij}\) is given as \(C_{ij}=(-1)^{i+j}M_{ij}\) where \(M_{ij}\) is the determinant of the submatrix of \(A\) obtained by deleting the \(i\)th row and the \(j\)th column of \(A\).

A quick search https://docs.sympy.org/latest/modules/matrices/matrices.html shows that there are two relevant functions in SymPy: cofactor and cofactor_matrix.

If these functions are not available in caracas they can be made so using sympy_func:

cofactor_matrix <- function(x) {
  sympy_func(x, "cofactor_matrix")
}

cofactor <- function(x, i, j) {
  # Python indexing starts at 0 - thus substract 1 to convert from R indexing
  # to Python indexing
  sympy_func(x, "cofactor", i - 1, j - 1)
}
A <- matrix_sym(3, 3, "a")
CC <- cofactor_matrix(A)
CC
#> [caracas]: Matrix([
#>            [ a22*a33 - a23*a32, -a21*a33 + a23*a31,  a21*a32 - a22*a31],
#>            [-a12*a33 + a13*a32,  a11*a33 - a13*a31, -a11*a32 + a12*a31],
#>            [ a12*a23 - a13*a22, -a11*a23 + a13*a21,  a11*a22 - a12*a21]])
cc <- cofactor(A, 1, 1)
cc
#> [caracas]: 1.0*a22*a33 - 1.0*a23*a32

We get the right answer

B <- t(CC) / det(A)
P <- A %*% B
P %>% simplify()
#> [caracas]: Matrix([
#>            [1, 0, 0],
#>            [0, 1, 0],
#>            [0, 0, 1]])