nloptr项目在nlopt 2.9.0+版本下的测试失败问题分析
nloptr作为R语言中一个重要的非线性优化接口包,近期在升级到nlopt 2.9.0及以上版本后出现了测试失败的情况。本文将从技术角度分析这一问题,并探讨解决方案。
问题现象
当nloptr项目构建并运行测试套件时,在nlopt 2.9.0及以上版本环境下,两个特定的测试用例会失败。这两个测试都涉及AUGLAG算法(一种使用两层优化器的算法):
- 测试文件test-nloptr.R第122行的测试用例
- 测试文件test-nloptr.R第144行的测试用例
失败的具体表现为:测试期望优化器返回状态status>0(表示某种失败状态),但实际上返回了-4(NLOPT_ROUNDOFF_LIMITED),表示由于舍入误差导致优化算法中断。
技术分析
从错误信息可以看出,优化过程最终以NLOPT_ROUNDOFF_LIMITED状态终止。这是nlopt定义的一种特殊状态,表示由于浮点舍入误差导致优化算法无法继续精确计算,但返回的结果可能仍然有用。
具体到这两个测试用例:
- 第一个测试使用NLOPT_LN_AUGLAG_EQ算法(基于导数的AUGLAG算法)配合本地NLOPT_LN_COBYLA算法
- 第二个测试使用NLOPT_LD_AUGLAG_EQ算法(不基于导数的AUGLAG算法)配合同样的本地算法
两个测试都设置了相对容差xtol_rel=1e-6和最大评估次数maxeval=10000。优化器在达到最大评估次数前就因舍入误差而终止。
解决方案讨论
项目维护者和贡献者经过讨论,提出了几种可能的解决方案:
-
调整容差参数:尝试修改xtol_rel或其他容差参数,避免优化器过于接近机器精度而触发舍入误差警告。
-
修改测试预期:考虑到NLOPT_ROUNDOFF_LIMITED也是一种有效的终止状态,可以修改测试条件接受这种状态。
-
暂时注释掉问题测试:作为临时解决方案,可以先注释掉这两个测试用例,待后续深入研究后再修复。
-
修改优化问题:选择另一个不会导致浮点精度问题的测试优化问题。
影响范围
这个问题不仅影响nloptr本身,还影响了依赖它的其他R包,如lme4和glmmTMB。特别是在CRAN的Fedora构建机器升级nlopt版本后,这一问题变得更加突出。
最终处理
项目维护者最终决定:
- 调整测试条件或暂时注释掉问题测试
- 准备新版本提交CRAN
- 后续深入研究AUGLAG算法在最新nlopt版本中的行为变化
这个问题也提醒我们,在数值优化领域,算法实现版本的升级可能会带来微妙的数值行为变化,需要特别注意测试用例的设计和预期结果的设置。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考