# 05 - Extending 'caracas In caracas: Computer Algebra

```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))
}
}
```

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 subtract 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
cc <- cofactor(A, 1, 1)
cc
```

```B <- t(CC) / det(A)