# Copyright (C) 2023 Avraham Adler. All Rights Reserved.
# SPDX-License-Identifier: LGPL-3.0-or-later
#
# File: test-wrapper-mlsl
# Author: Avraham Adler
# Date: 6 February 2023
#
# Test wrapper calls MLSL algorithm.
#
# Changelog:
# 2023-08-23: Change _stdout to _stdout and _lte to _true
#
library(nloptr)
tol <- 8e-8
## Functions for the algorithms
hartmann6 <- function(x) {
a <- c(1, 1.2, 3, 3.2)
A <- matrix(c(10, 0.05, 3, 17,
3, 10, 3.5, 8,
17, 17, 1.7, 0.05,
3.5, 0.1, 10, 10,
1.7, 8, 17, 0.1,
8, 14, 8, 14),
nrow = 4L, ncol = 6L)
B <- matrix(c(0.1312, 0.2329, 0.2348, 0.4047,
0.1696, 0.4135, 0.1451, 0.8828,
0.5569, 0.8307, 0.3522, 0.8732,
0.0124, 0.3736, 0.2883, 0.5743,
0.8283, 0.1004, 0.3047, 0.1091,
0.5886, 0.9991, 0.6650, 0.0381),
nrow = 4L, ncol = 6L)
fun <- 0
for (i in 1:4) {
fun <- fun - a[i] * exp(-sum(A[i, ] * (x - B[i, ]) ^ 2))
}
fun
}
hart.gr <- function(x) nl.grad(x, hartmann6)
x0 <- lb <- rep(0, 6L)
ub <- rep(1, 6L)
ctl <- list(xtol_rel = 1e-8, maxeval = 750L)
lopt <- list(algorithm = "NLOPT_LD_LBFGS", xtol_rel = 1e-4)
# Test printout if nl.info passed. The word "Call:" should be in output if
# passed and not if not passed.
expect_stdout(mlsl(x0 = x0, hartmann6, lower = lb, upper = ub, nl.info = TRUE),
"Call:", fixed = TRUE)
expect_silent(mlsl(x0 = x0, hartmann6, lower = lb, upper = ub))
# Test Warning
expect_warning(mlsl(x0, hartmann6, hart.gr, lb, ub, local.method = "MMA"),
"Only gradient-based LBFGS available as local met", fixed = TRUE)
# No passed gradient: Low discrepancy
mlslTest <- mlsl(x0, hartmann6, lower = lb, upper = ub, control = ctl)
mlslControl <- nloptr(x0 = x0,
eval_f = hartmann6,
eval_grad_f = hart.gr,
lb = lb,
ub = ub,
opts = list(algorithm = "NLOPT_GD_MLSL_LDS",
xtol_rel = 1e-8, maxeval = 750L,
local_opts = lopt))
expect_identical(mlslTest$par, mlslControl$solution)
expect_identical(mlslTest$value, mlslControl$objective)
expect_identical(mlslTest$iter, mlslControl$iterations)
expect_identical(mlslTest$convergence, mlslControl$status)
expect_identical(mlslTest$message, mlslControl$message)
# Passed gradient: No low discrepancy
mlslTest <- mlsl(x0, hartmann6, hart.gr, lb, ub, low.discrepancy = FALSE,
control = ctl)
mlslControl <- nloptr(x0 = x0,
eval_f = hartmann6,
eval_grad_f = hart.gr,
lb = lb,
ub = ub,
opts = list(algorithm = "NLOPT_GD_MLSL",
xtol_rel = 1e-8, maxeval = 750L,
local_opts = lopt))
expect_equal(mlslTest$par, mlslControl$solution, tolerance = tol)
expect_equal(mlslTest$value, mlslControl$objective, tolerance = tol)
# See https://nlopt.readthedocs.io/en/latest/NLopt_Reference/#stopping-criteria
# "This is not a strict maximum: the number of function evaluations may exceed
# maxeval slightly, depending upon the algorithm."
expect_true(abs(mlslTest$iter - mlslControl$iterations) <= 10L)
expect_identical(mlslTest$convergence, mlslControl$status)
expect_identical(mlslTest$message, mlslControl$message)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.