听起来您已经在使用此建议,但您需要更深入一点:"Use the source, Luke"。
我的出发点是,从 R 控制台,简单地输入
optim
这将打印该函数的 R 源代码。在那里我看到它在呼唤
.External2(C_optim, par, fn1, gr1, method, con, lower, upper)
我最喜欢的 R 源代码镜像是this GitHub repo。如果您前往那里,搜索“optim”,并仅过滤 C 结果,我们将找到最热门的 src/library/stats/src/optim.c。然后我们可以看到 C 级的 optim()(第 177 行)如何作用于 calls vmmin()(第 295 行)。
optim() 初始化这些参数的方式如下
int n length(par)
double *b vect(npar); dpar[i] = REAL(par)[i] / (OS->parscale[i])
double *Fmin 0.0
optimfn fn function defined in the C code
optimgr gr function defined in the C code
int maxit asInteger(getListElement(options, "maxit"))
int trace asInteger(getListElement(options, "trace"))
int *mask mask = (int *) R_alloc(npar, sizeof(int));
for (i = 0; i < npar; i++) mask[i] = 1;
double abstol asInteger(getListElement(options, "abstol"))
double reltol asInteger(getListElement(options, "reltol"))
int nREPORT asInteger(getListElement(options, "REPORT"));
void *ex OptStruct OS; /* tons of stuff done to this */
int *fncount 0
int *grcount 0
int *fail 0
我没有在这里详细介绍所有细节,但我相信这应该足以帮助您了解如何在自己的函数中使用这些东西,一旦您发现另一件事:控制列表在optim()。如果您在上面的.External2() 调用中注意到,有一个名为con 的参数。这在 R 代码中定义为
con <- list(trace = 0, fnscale = 1, parscale = rep.int(1, npar),
ndeps = rep.int(1e-3, npar),
maxit = 100L, abstol = -Inf, reltol = sqrt(.Machine$double.eps),
alpha = 1.0, beta = 0.5, gamma = 2.0,
REPORT = 10, warn.1d.NelderMead = TRUE,
type = 1,
lmm = 5, factr = 1e7, pgtol = 0,
tmax = 10, temp = 10.0)
虽然这些元素可以被control 参数中的用户输入覆盖,如果您查看help("optim"),您会看到
“控制”参数是一个可以提供以下任何组件的列表:
‘追踪’ ...
C 函数通过名称 options 引用此列表,您可以在我上面构建的表中看到多次引用该列表。