fnchk.Rdfnchk checks a user-provided R function, ffn.
fnchk(xpar, ffn, trace=0, ... )fnchk attempts to discover various errors in function setup in user-supplied
functions primarily intended for use in optimization calculations. There are always
more conditions that could be tested!
The output is a list consisting of list(fval=fval, infeasible=infeasible, excode=excode, msg=msg)
The calculated value of the function at parameters xpar if the function
can be evaluated.
FALSE if the function can be evaluated, TRUE if not.
An exit code, which has a relationship to
A text string giving information about the result of the function check: Messages and
the corresponding values of excode are:
fnchk OK; excode = 0;
infeasible = FALSE
Function returns INADMISSIBLE;
excode = -1; infeasible = TRUE
Function returns a vector not a scalar;
excode = -4; infeasible = TRUE
Function returns a list not a scalar;
excode = -4; infeasible = TRUE
Function returns a matrix list not a scalar;
excode = -4; infeasible = TRUE
Function returns an array not a scalar;
excode = -4; infeasible = TRUE
Function returned not length 1, despite not vector, matrix or array;
excode = -4; infeasible = TRUE
Function returned non-numeric value; excode = 0;
excode = -1; infeasible = TRUE
Function returned Inf or NA (non-computable);
excode = -1; infeasible = TRUE
# Want to illustrate each case.
# Ben Bolker idea for a function that is NOT scalar
# rm(list=ls())
# library(optimx)
sessionInfo()
#> R version 4.4.1 (2024-06-14)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 22.04.5 LTS
#>
#> Matrix products: default
#> BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
#> LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so; LAPACK version 3.10.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_US.UTF-8 LC_COLLATE=C
#> [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
#> [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
#> [9] LC_ADDRESS=C LC_TELEPHONE=C
#> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
#>
#> time zone: Etc/UTC
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] optextras_2019-12.4
#>
#> loaded via a namespace (and not attached):
#> [1] vctrs_0.6.5 cli_3.6.5 knitr_1.50
#> [4] rlang_1.1.6 xfun_0.53 purrr_1.1.0
#> [7] textshaping_1.0.3 glue_1.8.0 htmltools_0.5.8.1
#> [10] ragg_1.5.0 fansi_1.0.6 rmarkdown_2.30
#> [13] rappdirs_0.3.3 evaluate_1.0.5 tibble_3.3.0
#> [16] fastmap_1.2.0 numDeriv_2016.8-1.1 yaml_2.3.10
#> [19] lifecycle_1.0.4 httr2_1.2.1 memoise_2.0.1
#> [22] whisker_0.4.1 compiler_4.4.1 fs_1.6.6
#> [25] downlit_0.4.4 pkgconfig_2.0.3 systemfonts_1.2.3
#> [28] digest_0.6.37 R6_2.6.1 curl_7.0.0
#> [31] pillar_1.11.1 magrittr_2.0.4 tools_4.4.1
#> [34] withr_3.0.2 pkgdown_2.1.3 xml2_1.4.0
#> [37] cachem_1.1.0 desc_1.4.3
benbad<-function(x, y){
# y may be provided with different structures
f<-(x-y)^2
} # very simple, but ...
y<-1:10
x<-c(1)
cat("fc01: test benbad() with y=1:10, x=c(1)\n")
#> fc01: test benbad() with y=1:10, x=c(1)
fc01<-fnchk(x, benbad, trace=4, y)
#> fnchk: ffn =
#> function (x, y)
#> {
#> f <- (x - y)^2
#> }
#> <environment: 0x555a48bf1fc8>
#> fnchk: xpar:[1] 1
#> fnchk: dots:[[1]]
#> [1] 1 2 3 4 5 6 7 8 9 10
#>
#> about to call ffn(xpar, ...)
#> ffn:function (x, y)
#> {
#> f <- (x - y)^2
#> }
#> <environment: 0x555a48bf1fc8>
#> xpar & dots:[1] 1
#> [[1]]
#> [1] 1 2 3 4 5 6 7 8 9 10
#>
#> test in fnchk: [1] 0 1 4 9 16 25 36 49 64 81
#> Function value at supplied parameters = [1] 0 1 4 9 16 25 36 49 64 81
#> num [1:10] 0 1 4 9 16 25 36 49 64 81
#> NULL
#> [1] TRUE
#> Function evaluation returns a vector not a scalar
#> Function evaluation returned non-numeric value
#> Function evaluation returned Inf or NA (non-computable)
#> Function at given point= NA
print(fc01)
#> $fval
#> [1] NA
#>
#> $infeasible
#> [1] TRUE
#>
#> $excode
#> [1] -1
#>
#> $msg
#> [1] "Function evaluation returned Inf or NA (non-computable)"
#>
y<-as.vector(y)
cat("fc02: test benbad() with y=as.vector(1:10), x=c(1)\n")
#> fc02: test benbad() with y=as.vector(1:10), x=c(1)
fc02<-fnchk(x, benbad, trace=1, y)
#> Function value at supplied parameters = [1] 0 1 4 9 16 25 36 49 64 81
#> num [1:10] 0 1 4 9 16 25 36 49 64 81
#> NULL
#> [1] TRUE
#> Function evaluation returns a vector not a scalar
#> Function evaluation returned non-numeric value
#> Function evaluation returned Inf or NA (non-computable)
#> Function at given point= NA
print(fc02)
#> $fval
#> [1] NA
#>
#> $infeasible
#> [1] TRUE
#>
#> $excode
#> [1] -1
#>
#> $msg
#> [1] "Function evaluation returned Inf or NA (non-computable)"
#>
y<-as.matrix(y)
cat("fc03: test benbad() with y=as.matrix(1:10), x=c(1)\n")
#> fc03: test benbad() with y=as.matrix(1:10), x=c(1)
fc03<-fnchk(x, benbad, trace=1, y)
#> Function value at supplied parameters = [,1]
#> [1,] 0
#> [2,] 1
#> [3,] 4
#> [4,] 9
#> [5,] 16
#> [6,] 25
#> [7,] 36
#> [8,] 49
#> [9,] 64
#> [10,] 81
#> num [1:10, 1] 0 1 4 9 16 25 36 49 64 81
#> NULL
#> [1] FALSE
#> Function evaluation returns a matrix list not a scalar
#> Function evaluation returned non-numeric value
#> Function evaluation returned Inf or NA (non-computable)
#> Function at given point= NA
print(fc03)
#> $fval
#> [1] NA
#>
#> $infeasible
#> [1] TRUE
#>
#> $excode
#> [1] -1
#>
#> $msg
#> [1] "Function evaluation returned Inf or NA (non-computable)"
#>
y<-as.array(y)
cat("fc04: test benbad() with y=as.array(1:10), x=c(1)\n")
#> fc04: test benbad() with y=as.array(1:10), x=c(1)
fc04<-fnchk(x, benbad, trace=1, y)
#> Function value at supplied parameters = [,1]
#> [1,] 0
#> [2,] 1
#> [3,] 4
#> [4,] 9
#> [5,] 16
#> [6,] 25
#> [7,] 36
#> [8,] 49
#> [9,] 64
#> [10,] 81
#> num [1:10, 1] 0 1 4 9 16 25 36 49 64 81
#> NULL
#> [1] FALSE
#> Function evaluation returns a matrix list not a scalar
#> Function evaluation returned non-numeric value
#> Function evaluation returned Inf or NA (non-computable)
#> Function at given point= NA
print(fc04)
#> $fval
#> [1] NA
#>
#> $infeasible
#> [1] TRUE
#>
#> $excode
#> [1] -1
#>
#> $msg
#> [1] "Function evaluation returned Inf or NA (non-computable)"
#>
y<-"This is a string"
cat("test benbad() with y a string, x=c(1)\n")
#> test benbad() with y a string, x=c(1)
fc05<-fnchk(x, benbad, trace=1, y)
#> Error in x - y : non-numeric argument to binary operator
#> Function value at supplied parameters =[1] NA
#> attr(,"inadmissible")
#> [1] TRUE
#> logi NA
#> - attr(*, "inadmissible")= logi TRUE
#> NULL
#> [1] FALSE
#> Function evaluation returns INADMISSIBLE
#> Function evaluation returned non-numeric value
#> Function evaluation returned Inf or NA (non-computable)
#> Function at given point= NA
print(fc05)
#> $fval
#> [1] NA
#>
#> $infeasible
#> [1] TRUE
#>
#> $excode
#> [1] -1
#>
#> $msg
#> [1] "Function evaluation returned Inf or NA (non-computable)"
#>
cat("fnchk with Rosenbrock\n")
#> fnchk with Rosenbrock
fr <- function(x) { ## Rosenbrock Banana function
x1 <- x[1]
x2 <- x[2]
100 * (x2 - x1 * x1)^2 + (1 - x1)^2
}
xtrad<-c(-1.2,1)
ros1<-fnchk(xtrad, fr, trace=1)
#> Function value at supplied parameters =[1] 24.2
#> num 24.2
#> NULL
#> [1] TRUE
#> Function at given point= 24.2
print(ros1)
#> $fval
#> [1] 24.2
#>
#> $infeasible
#> [1] FALSE
#>
#> $excode
#> [1] 0
#>
#> $msg
#> [1] "fnchk OK"
#>
npar<-2
opros<-list2env(list(fn=fr, gr=NULL, hess=NULL, MAXIMIZE=FALSE, PARSCALE=rep(1,npar), FNSCALE=1,
KFN=0, KGR=0, KHESS=0, dots=NULL))
uros1<-fnchk(xtrad, fr, trace=1)
#> Function value at supplied parameters =[1] 24.2
#> num 24.2
#> NULL
#> [1] TRUE
#> Function at given point= 24.2
print(uros1)
#> $fval
#> [1] 24.2
#>
#> $infeasible
#> [1] FALSE
#>
#> $excode
#> [1] 0
#>
#> $msg
#> [1] "fnchk OK"
#>