The DiffEq ecosystem provides an extensive interface for declaring extra functions associated with the differential equation's data. In traditional libraries there is usually only one option: the Jacobian. However, we allow for a large array of pre-computed functions to speed up the calculations. This is offered via function overloading (or overloaded types) and allows for these extra features to be offered without cluttering the problem interface.

## Declaring Explicit Jacobians

The most standard case, declaring a function for a Jacobian is done by overloading the function `f(du,u,p,t)` with an in-place updating function for the Jacobian: `f(Val{:jac},J,u,p,t)` where the value type is used for dispatch. For example, take the LotkaVolterra model:

``````function f(du,u,p,t)
du = 2.0 * u - 1.2 * u*u
du = -3 * u + u*u
end``````

To declare the Jacobian we simply add the dispatch:

``````function f(::Type{Val{:jac}},J,u,p,t)
J[1,1] = 2.0 - 1.2 * u
J[1,2] = -1.2 * u
J[2,1] = 1 * u
J[2,2] = -3 + u
nothing
end``````

Note that this can also be done by generating a call-overloaded type. Indeed, this is what ParameterizedFunctions.jl does, so see its README.

## Declaring Explicit Jacobians for DAEs

For fully implicit ODEs (`DAEProblem`s), a slightly different Jacobian function is necessary. For the DAE

\[G(du,u,p,t) = res\]

The Jacobian should be given in the form `dG/d(du) + gamma*dG/du` where `gamma` is given by the solver. This means that the signature is:

``f(::Type{Val{:jac}},J,du,u,p,gamma,t)``

For example, for the equation

``````function testjac(res,du,u,p,t)
res = du - 2.0 * u + 1.2 * u*u
res = du -3 * u - u*u
end``````

we would define the Jacobian as:

``````function testjac(::Type{Val{:jac}},J,du,u,p,gamma,t)
J[1,1] = gamma - 2.0 + 1.2 * u
J[1,2] = 1.2 * u
J[2,1] = - 1 * u
J[2,2] = gamma - 3 - u
nothing
end``````

## Other Available Functions

The full interface available to the solvers is as follows:

``````f(du,u,p,t) # Call the function
f(Val{:analytic},u0,p,t) # The analytical solution. Used in testing
Overloads which require parameters should subtype `ParameterizedFunction`. These are all in-place functions which write into the last variable. See solver documentation specifics to know which optimizations the algorithms can use.