我最近在使用 GSL 时遇到了一个非常奇怪的问题。我试图通过要求 GSL 找到函数负像的最小值来找到丑陋函数的最大值。到目前为止,我一直在使用它的大多数功能都可以正常工作,但是对于某些功能,我会遇到错误。
具体来说,当我将函数提供给最小值查找器时,ruby GSL gem 会引发异常,指出给定的端点没有包含最小值。但是,给定的端点确实包含最小值;此外,结果似乎取决于给出的初步估计。
当我要求 GSL 从猜测 0.0 开始找到最小值时,我得到了错误。当我要求它从猜测 2.0 开始找到最小值时,它找到了最小值。GSL 会抱怨在给定的时间间隔内没有最小值,这似乎很奇怪,这取决于最初的猜测。
下面是我为重现此错误而编写的脚本。我正在使用 GSL 版本 1.15 和最新版本的 Ruby/GSL gem 包装器,以及 Ruby 版本 1.9.3p392。
有人可以试试这个脚本,看看他们是否可以重现这些结果?我想将此作为错误报告给 GSL 维护人员,但如果我能在其他人的计算机上也发生错误,我会感觉更好。
脚本中提供了三个初始最小猜测值;从 0.0 开始会导致 GSL 抛出上述错误。从 1.0 开始会导致 GSL 报告最小值,而这恰好是局部最小值。从 2.0 开始会导致 GSL 报告另一个最小值,这似乎是我正在寻找的全局最小值。
这是我的测试脚本:
require("gsl")
include GSL::Min
function = Function.alloc { |beta| -(((6160558822864*(Math.exp(4*beta))+523830424923*(Math.exp(3*beta))+1415357447750*(Math.exp(5*beta))+7106224104*(Math.exp(6*beta)))/(385034926429*(Math.exp(4*beta))+58203380547*(Math.exp(3*beta))+56614297910*(Math.exp(5*beta))+197395114*(Math.exp(6*beta))))-((1540139705716*(Math.exp(4*beta))+174610141641*(Math.exp(3*beta))+283071489550*(Math.exp(5*beta))+1184370684*(Math.exp(6*beta)))*(1540139705716*(Math.exp(4*beta))+174610141641*(Math.exp(3*beta))+283071489550*(Math.exp(5*beta))+1184370684*(Math.exp(6*beta)))/(385034926429*(Math.exp(4*beta))+58203380547*(Math.exp(3*beta))+56614297910*(Math.exp(5*beta))+197395114*(Math.exp(6*beta)))**2)) }
def find_maximum(fn1)
iter = 0; max_iter = 500
minimum = 0.0 # reasonable initial guess; causes GSL to crash!
#minimum = 1.0 # another initial guess, gets a local min
#minimum = 2.0 # this guess gets what appears to be the global min
a = -6.0
b = 6.0
#pretty wide interval
gmf = FMinimizer.alloc(FMinimizer::BRENT)
gmf.set(fn1, minimum, a, b)
#THIS line is failing (sometimes), complaining that the interval given doesn't contain a minimum. Which it DOES.
begin
iter += 1
status = gmf.iterate
status = gmf.test_interval(0.001, 0.0)
# puts("Converged:") if status == GSL::SUCCESS
a = gmf.x_lower
b = gmf.x_upper
minimum = gmf.x_minimum
# printf("%5d [%.7f, %.7f] %.7f %.7f\n",
# iter, a, b, minimum, b - a);
end while status == GSL::CONTINUE and iter < max_iter
minimum
end
puts find_maximum(function)
请让我知道当您尝试此代码时会发生什么,并注释掉最小值的不同初始值。如果您能看到为什么这实际上是 GSL 的预期行为的原因,我也将不胜感激。
感谢您的帮助!