r - R 中的优化:Levenberg-Marquardt 在 minpack.lm 中使用 nls.lm:将“maxiter”重置为 1024
问题描述
我正在尝试通过使用 Rosenbrock 函数来了解如何nls.lm
在 R 库minpack.lm
中使用,以查看算法是否在 f(x,y) = (1,1) 处收敛到全局最小值。无论有没有分析雅可比行列式,我都会这样做。在这两种情况下,我都会收到一条警告,告诉我算法已决定将调用中指定的最大迭代次数恢复nls.lm
为 1024:
Warning messages:
1: In nls.lm(par = initpar, fn = objective_rosenbrock, jac = gradient_rosenbrock, :
resetting `maxiter' to 1024!
2: In nls.lm(par = initpar, fn = objective_rosenbrock, jac = gradient_rosenbrock, :
lmder: info = -1. Number of iterations has reached `maxiter' == 1024.
由于我最初的猜测是 (-1.2, 1.0),因此该算法永远不会完全达到 (1,1)。我在 GitHub 上找到了该库的源代码,以下代码行与此处相关:
https://github.com/cran/minpack.lm/blob/master/src/nls_lm.c
OS->maxiter = INTEGER_VALUE(getListElement(control, "maxiter"));
if(OS->maxiter > 1024) {
OS->maxiter = 1024;
warning("resetting `maxiter' to 1024!");
}
为什么最大迭代次数限制为 1024 是否有任何逻辑?有位和 2^10 的东西?我想将该库用于不同的应用程序,但是这个迭代上限可能会阻止这种情况。任何见解将不胜感激。
解决方案
Git blame说这个限制最大迭代的代码是在 2008 年的 1.1-0 版本中引入的。包的 NEWS 文件只能追溯到 1.1-6 版本。除了您指向的那个之外,我在任何公共回购中都找不到代码(这只是一个 CRAN 镜像;它不包含来自开发人员的任何评论/提交消息/等,这些可能会给我们提供线索。)
除了联系维护者之外,我认为很难弄清楚这个限制的基本原理是什么。
不过我确实有一些猜测。
maxiter
代码中实际使用的唯一地方是这里和这里——在 R 代码中,而不是 Fortran 或 C 代码中,所以我们似乎极不可能处理像 10 位无符号整数类型这样的东西(这似乎是一个不太可能的选择任何状况之下)。我认为存在限制,因为我们还定义了一个缓冲区来保存跟踪信息:
double rsstrace[1024];
如您所见,它被硬编码为 1024 的长度。如果我们试图将 1025 次迭代的跟踪信息填充到这个数组中,可能会发生不好的事情......
我的建议:
- 将代码中“1024”的所有实例更改为更大的值,看看会发生什么。只有四个:
$ find . -type f -exec grep -Hn 1024 {} \;
./src/nls_lm.c:141: if(OS->maxiter > 1024) {
./src/nls_lm.c:142: OS->maxiter = 1024;
./src/nls_lm.c:143: warning("resetting `maxiter' to 1024!");
./src/minpack_lm.h:20: double rsstrace[1024];
- 最好
#define MAXITER 2048
(或其他)输入src/minpack_lm.h
并使用它而不是数值。 - 联系维护者 (
maintainer("minpack.lm")
) 并询问他们这个问题。
推荐阅读
- sql - 将三个表之间的计数(*)相加
- spring-boot - 在Spring boot中,如何将表单动作中的jsp表单输入的值作为参数传递
- python - 权限错误 python jupyterhub。怎么解决?
- javascript - 如何在 div id 上创建 .click() 函数,但 id 在数组中?
- vba - 将范围值随机分配到更大的范围
- bash - crontab:每月停止一小时
- java - 禁用 Kafka 日志
- postgresql - PostgreSQL中&&运算符的时间复杂度
- javascript - 使用KeyboardEvent.code替换KeyboardEvent.keyCode,但为空
- mongodb - 如何在 mongo db 中更新具有给定值的指定字段