The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Overview

Function Result Colouring Derivative mode
jacobian dense matrix optional forward or reverse
jacobian_sparse CSC sparse matrix required forward
jacobian_banded band matrix required forward

All three take an inner function f mapping a double vector to a double vector, the point x and an optional data argument passed to f unchanged.

Example function

A 1-D diffusion term: every output depends only on its neighbours, so the Jacobian is tridiagonal.

f <- function(x) {
  argtypes(x |> type(vec(double)))
  diffusion <- function(y) {
    argtypes(y |> type(vec(double)))
    returntype(vec(double))
    n <- length(y)
    out <- numeric(n)
    out[[1L]] <- y[[2L]] - y[[1L]]
    for (i in 2L:(n - 1L)) {
      out[[i]] <- y[[i - 1L]] - 2 * y[[i]] * y[[i]] + y[[i + 1L]]
    }
    out[[n]] <- y[[n - 1L]] - y[[n]]
    return(out)
  }
  return(jacobian(diffusion, x))
}
fcpp <- ast2ast::translate(f, derivative = "forward")
fcpp(c(0.3, 0.7, 1.1, 0.2, 0.9, 1.4))

Dense

jacobian(f, x) returns the m-by-n matrix. In forward mode it needs one sweep per column, in reverse mode one sweep per row.

Colouring

Columns that share no row can be computed in one forward sweep. For the tridiagonal example three sweeps are enough, independent of length(x).

return(jacobian(diffusion, x, colouring = "static", n = 6L))
return(jacobian(diffusion, x, colouring = "runtime"))

Colouring requires derivative = "forward".

Sparse and banded

jacobian_sparse and jacobian_banded compute and store only the entries of the sparsity pattern. Thus, colouring is required:

J <- jacobian_sparse(diffusion, x, colouring = "static", n = 6L)
J <- jacobian_banded(diffusion, x, colouring = "runtime")

Without it the translation fails:

jacobian_sparse needs colouring = "static", n = <integer literal> or colouring = "runtime"

Layouts

Both are stored as in SUNDIALS, so they can be handed to its solvers directly.

  • jacobian_sparse: CSC, 0-based (SUNMatrix_Sparse). Fields J$m, J$n, J$indexptrs, J$indexvals, J$data.
  • jacobian_banded: square, LAPACK band layout (SUNMatrix_Band). Fields J$n, J$mu, J$ml, J$ldim, J$data; A(i, j) is at data[j * ldim + mu + i - j] (0-based), ldim = mu + ml + 1.

For the tridiagonal 6 x 6 example: mu = ml = 1, ldim = 3, length(J$data) = 18.

Returned to R

Both are returned to R as a Matrix::dgCMatrix (package Matrix has to be installed):

# f from above with return(jacobian_sparse(diffusion, x, colouring = "runtime"))
J <- fcpp(c(0.3, 0.7, 1.1, 0.2, 0.9, 1.4))
class(J)
# [1] "dgCMatrix"
as.matrix(J)

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.