# 05 - Extending ‘caracas’

    library(caracas)

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
    #> c: ⎡a₂₂⋅a₃₃ - a₂₃⋅a₃₂   -a₂₁⋅a₃₃ + a₂₃⋅a₃₁  a₂₁⋅a₃₂ - a₂₂⋅a₃₁ ⎤
    #>    ⎢                                                          ⎥
    #>    ⎢-a₁₂⋅a₃₃ + a₁₃⋅a₃₂  a₁₁⋅a₃₃ - a₁₃⋅a₃₁   -a₁₁⋅a₃₂ + a₁₂⋅a₃₁⎥
    #>    ⎢                                                          ⎥
    #>    ⎣a₁₂⋅a₂₃ - a₁₃⋅a₂₂   -a₁₁⋅a₂₃ + a₁₃⋅a₂₁  a₁₁⋅a₂₂ - a₁₂⋅a₂₁ ⎦
    cc <- cofactor(A, 1, 1)
    cc
    #> c: a₂₂⋅a₃₃ - a₂₃⋅a₃₂

We get the right answer

    B <- t(CC) / det(A)
    P <- A %*% B
    P %>% simplify()
    #> c: ⎡1  0  0⎤
    #>    ⎢       ⎥
    #>    ⎢0  1  0⎥
    #>    ⎢       ⎥
    #>    ⎣0  0  1⎦