# Copyright (C) 201 Jelmer Ypma. All Rights Reserved.
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# File: test-derivative-checker.R
# Author: Jelmer Ypma
# Date: 24 July 2010
#
# Maintenance assumed by Avraham Adler (AA) on 2023-02-10
#
# Example showing results of the derivative checker and finite-difference
#
# Changelog:
# 2013-10-27: Changed example to use unit testing framework testthat.
# 2019-12-12: Corrected warnings and using updated testtthat framework (AA)
# 2023-02-10: Remove wrapping tests in "test_that" to reduce duplication.
# and add explicit accuracy checks for nloptr:::finite.diff.R (AA)
# 2023-08-23: Prefix finite.diff with nloptr::: as part of move to tinytest
#
library(nloptr)
# Test derivative checker.
tol <- 1e-7
# Define objective function.
f <- function(x, a) sum((x - a) ^ 2)
# Define gradient function without errors.
f_grad <- function(x, a) 2 * (x - a)
# Generated a using:
# > set.seed(3141)
# > a <- runif(10)
# > dump("a", file = "")
a <- c(0.75499595934525132, 0.9649918619543314, 0.041430773446336389,
0.42781219445168972, 0.65170943737030029, 0.83836922678165138,
0.77428539283573627, 0.53199269832111895, 0.76871572202071548,
0.7851746492087841)
# Test nloptr:::finite.diff on multivariate scalar function
expect_equal(nloptr:::finite.diff(f, 1:10, a = a), f_grad(1:10, a = a),
tolerance = tol)
expect_equal(nloptr:::finite.diff(f, 1:10, a = a), nl.grad(1:10, f, a = a),
tolerance = tol)
# Test nloptr:::finite.diff on multivariate Jacobian of vector function
x0 <- 1:3
fn1 <- function(x) {
c(3 * x[1L] ^ 2 * x[2L] * log(x[3L]), x[3] ^ 3 - 2 * x[1L] * x[2L])
}
jac1 <- function(x) {
matrix(c(6 * x[1L] * x[2L] * log(x[3L]),
3 * x[1L] ^ 2 * log(x[3L]),
3 * x[1L] ^ 2 * x[2L] / x[3L],
-2 * x[2L], -2 * x[1L], 3 * x[3L] ^ 2),
nrow = 2L, byrow = TRUE)
}
expect_equal(nloptr:::finite.diff(fn1, x0), jac1(x0), tolerance = tol)
res <- suppressMessages(
check.derivatives(
.x = 1:10,
func = f,
func_grad = f_grad,
check_derivatives_print = "none",
a = a
)
)
expect_identical(sum(res$flag_derivative_warning), 0L)
# Define gradient function with 1 error.
f_grad <- function(x, a) 2 * (x - a) + c(0, 0.1, rep(0, 8L))
res <- suppressMessages(
check.derivatives(
.x = 1:10,
func = f,
func_grad = f_grad,
check_derivatives_print = "none",
a = a
)
)
expect_identical(sum(res$flag_derivative_warning), 1L)
# Define objective function.
g <- function(x, a) c(sum(x - a), sum((x - a) ^ 2))
# Define gradient function with 2 errors.
g_grad <- function(x, a) {
rbind(rep(1, length(x)) + c(0, 0.01, rep(0, 8L)),
2 * (x - a) + c(0, 0.1, rep(0, 8L)))
}
res <- suppressMessages(
check.derivatives(
.x = 1:10,
func = g,
func_grad = g_grad,
check_derivatives_print = "none",
a = a
)
)
expect_identical(sum(res$flag_derivative_warning), 2L)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.