Skip to contents

This function compares the analytic gradients of a function with a finite difference approximation and prints the results of these checks.

Usage

check.derivatives(
  .x,
  func,
  func_grad,
  check_derivatives_tol = 1e-04,
  check_derivatives_print = "all",
  func_grad_name = "grad_f",
  ...
)

Arguments

.x

point at which the comparison is done.

func

function to be evaluated.

func_grad

function calculating the analytic gradients.

check_derivatives_tol

option determining when differences between the analytic gradient and its finite difference approximation are flagged as an error.

check_derivatives_print

option related to the amount of output. 'all' means that all comparisons are shown, 'errors' only shows comparisons that are flagged as an error, and 'none' shows the number of errors only.

func_grad_name

option to change the name of the gradient function that shows up in the output.

...

further arguments passed to the functions func and func_grad.

Value

The return value contains a list with the analytic gradient, its finite difference approximation, the relative errors, and vector comparing the relative errors to the tolerance.

See also

Author

Jelmer Ypma

Examples


library('nloptr')

# example with correct gradient
f <- function(x, a) sum((x - a) ^ 2)

f_grad <- function(x, a)  2 * (x - a)

check.derivatives(.x = 1:10, func = f, func_grad = f_grad,
          check_derivatives_print = 'none', a = runif(10))
#> Derivative checker results: 0 error(s) detected.
#> $analytic
#>  [1]  1.461236  3.661304  5.932209  7.642430  8.716669 11.954245 13.983350
#>  [8] 15.214606 16.372239 19.247503
#> 
#> $finite_difference
#>  [1]  1.461239  3.661304  5.932209  7.642430  8.716669 11.954245 13.983350
#>  [8] 15.214606 16.372239 19.247503
#> 
#> $relative_error
#>  [1] 1.788727e-06 1.967545e-07 4.380139e-08 4.106753e-08 2.239447e-08
#>  [6] 8.413985e-09 9.619268e-09 1.331370e-08 3.355223e-08 9.943461e-09
#> 
#> $flag_derivative_warning
#>  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> 

# example with incorrect gradient
f_grad <- function(x, a)  2 * (x - a) + c(0, 0.1, rep(0, 8))

check.derivatives(.x = 1:10, func = f, func_grad = f_grad,
          check_derivatives_print = 'errors', a = runif(10))
#> Derivative checker results: 1 error(s) detected.
#> 
#> * grad_f[ 2] = 3.570163e+00 ~ 3.470163e+00   [2.881706e-02]
#> 
#> $analytic
#>  [1]  1.238376  3.570163  5.121331  7.084786  8.918585 10.668640 13.774602
#>  [8] 15.563266 16.424327 19.804294
#> 
#> $finite_difference
#>  [1]  1.238377  3.470163  5.121332  7.084785  8.918585 10.668641 13.774602
#>  [8] 15.563266 16.424327 19.804294
#> 
#> $relative_error
#>  [1] 7.952941e-07 2.881706e-02 3.233928e-08 3.332356e-08 3.358306e-08
#>  [6] 4.051958e-08 3.800736e-09 8.706877e-09 7.393552e-09 1.433832e-08
#> 
#> $flag_derivative_warning
#>  [1] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> 

# example with incorrect gradient of vector-valued function
g <- function(x, a) c(sum(x - a), sum((x - a) ^ 2))

g_grad <- function(x, a) {
   rbind(rep(1, length(x)) + c(0, 0.01, rep(0, 8)),
   2 * (x - a) + c(0, 0.1, rep(0, 8)))
}

check.derivatives(.x = 1:10, func = g, func_grad = g_grad,
          check_derivatives_print = 'all', a = runif(10))
#> Derivative checker results: 2 error(s) detected.
#> 
#>   grad_f[1,  1] = 1.000000e+00 ~ 1.000000e+00   [0.000000e+00]
#>   grad_f[2,  1] = 5.803391e-01 ~ 5.803413e-01   [3.914069e-06]
#> * grad_f[1,  2] = 1.010000e+00 ~ 1.000000e+00   [1.000000e-02]
#> * grad_f[2,  2] = 3.664354e+00 ~ 3.564354e+00   [2.805557e-02]
#>   grad_f[1,  3] = 1.000000e+00 ~ 1.000000e+00   [0.000000e+00]
#>   grad_f[2,  3] = 5.464113e+00 ~ 5.464113e+00   [3.923042e-08]
#>   grad_f[1,  4] = 1.000000e+00 ~ 1.000000e+00   [0.000000e+00]
#>   grad_f[2,  4] = 6.990464e+00 ~ 6.990464e+00   [1.632038e-08]
#>   grad_f[1,  5] = 1.000000e+00 ~ 1.000000e+00   [0.000000e+00]
#>   grad_f[2,  5] = 9.622826e+00 ~ 9.622826e+00   [2.484410e-08]
#>   grad_f[1,  6] = 1.000000e+00 ~ 1.000000e+00   [0.000000e+00]
#>   grad_f[2,  6] = 1.112114e+01 ~ 1.112114e+01   [7.536909e-09]
#>   grad_f[1,  7] = 1.000000e+00 ~ 1.000000e+00   [0.000000e+00]
#>   grad_f[2,  7] = 1.266036e+01 ~ 1.266036e+01   [2.294086e-08]
#>   grad_f[1,  8] = 1.000000e+00 ~ 1.000000e+00   [0.000000e+00]
#>   grad_f[2,  8] = 1.551823e+01 ~ 1.551823e+01   [1.536377e-08]
#>   grad_f[1,  9] = 1.000000e+00 ~ 1.000000e+00   [0.000000e+00]
#>   grad_f[2,  9] = 1.621347e+01 ~ 1.621347e+01   [1.545171e-08]
#>   grad_f[1, 10] = 1.000000e+00 ~ 1.000000e+00   [0.000000e+00]
#>   grad_f[2, 10] = 1.823449e+01 ~ 1.823449e+01   [1.685468e-08]
#> 
#> $analytic
#>           [,1]     [,2]     [,3]     [,4]     [,5]     [,6]     [,7]     [,8]
#> [1,] 1.0000000 1.010000 1.000000 1.000000 1.000000  1.00000  1.00000  1.00000
#> [2,] 0.5803391 3.664354 5.464113 6.990464 9.622826 11.12114 12.66036 15.51823
#>          [,9]    [,10]
#> [1,]  1.00000  1.00000
#> [2,] 16.21347 18.23449
#> 
#> $finite_difference
#>           [,1]     [,2]     [,3]     [,4]     [,5]     [,6]     [,7]     [,8]
#> [1,] 1.0000000 1.000000 1.000000 1.000000 1.000000  1.00000  1.00000  1.00000
#> [2,] 0.5803413 3.564354 5.464113 6.990464 9.622826 11.12114 12.66036 15.51823
#>          [,9]    [,10]
#> [1,]  1.00000  1.00000
#> [2,] 16.21347 18.23449
#> 
#> $relative_error
#>              [,1]       [,2]         [,3]         [,4]        [,5]         [,6]
#> [1,] 0.000000e+00 0.01000000 0.000000e+00 0.000000e+00 0.00000e+00 0.000000e+00
#> [2,] 3.914069e-06 0.02805557 3.923042e-08 1.632038e-08 2.48441e-08 7.536909e-09
#>              [,7]         [,8]         [,9]        [,10]
#> [1,] 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00
#> [2,] 2.294086e-08 1.536377e-08 1.545171e-08 1.685468e-08
#> 
#> $flag_derivative_warning
#>       [,1] [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
#> [1,] FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#> [2,] FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
#>