Compute the Jacobian.
Note
The output jac only includes the elements of the nonlinear Jacobian.
If the constant elements are being handled separately (if the linear
pattern is available), then those elements can be obtained by
calling get_sparsity_pattern if required.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(numdiff_type), | intent(inout) | :: | me | |||
| real(kind=wp), | intent(in), | dimension(:) | :: | x |
vector of variables (size |
|
| real(kind=wp), | intent(out), | dimension(:), allocatable | :: | jac |
sparse jacobian vector |
|
| real(kind=wp), | intent(in), | optional, | dimension(me%m) | :: | fx |
the function value at |
subroutine compute_jacobian(me,x,jac,fx) implicit none class(numdiff_type),intent(inout) :: me real(wp),dimension(:),intent(in) :: x !! vector of variables (size `n`) real(wp),dimension(:),allocatable,intent(out) :: jac !! sparse jacobian vector real(wp),dimension(me%m),intent(in),optional :: fx !! the function value at `x` (size `m`), if it !! is already known. if present, it is used instead !! of calling the function at `x` (which saves one !! function evaluation for methods that use \( f(x) \), !! such as forward differences). all the rows in the !! sparsity pattern must be set. real(wp),dimension(me%n) :: dx !! absolute perturbation (>0) for each variable if (me%exception_raised) return ! check for exceptions ! if we don't have a sparsity pattern yet then compute it: ! [also computes the indices vector] if (.not. me%sparsity%sparsity_computed) then if (.not. associated(me%compute_sparsity)) then ! sparsity_mode=3, but set_sparsity_pattern was not called call me%raise_exception(30,'compute_jacobian',& 'the sparsity pattern has not been set.') return end if call me%compute_sparsity(x) if (me%exception_raised) return ! check for exceptions end if if (me%sparsity%num_nonzero_elements==0) return ! size the jacobian vector: allocate(jac(me%sparsity%num_nonzero_elements)) ! compute dx vector: if (.not. me%use_diff) then ! only need this for the finite difference methods (not diff) call me%compute_perturbation_vector(x,dx) if (me%exception_raised) return ! check for exceptions end if ! compute the jacobian: if (associated(me%jacobian_function)) then call me%jacobian_function(x,dx,jac,fx) else call me%raise_exception(22,'compute_jacobian',& 'jacobian_function has not been associated.') return end if end subroutine compute_jacobian