Optim.jl 使用 Inf 作为绑定时单变量有界优化混淆输出
Optim.jl univariate bounded optimization confusing output when using Inf as bound
以下是说明我的问题的独立示例。
using Optim
χI = 3
ψI = 0.5
ϕI(z) = z^-ψI
λ = 1.0532733
V0 = 0.8522423425
zE = 0.5986
wRD = 0.72166623555
objective1(z) = -(z * χI * ϕI(z + zE) * (λ-1) * V0 - z * ( wRD ))
objective2(z) = -1 * objective1(z)
lower = 0.01
upper = Inf
plot(0:0.01:0.1,objective1,title = "objective1")
png("/home/nico/Desktop/objective1.png")
plot(0:0.01:0.1,objective2, title = "objective2")
png("/home/nico/Desktop/objective2.png")
results1 = optimize(objective1,lower,upper)
results2 = optimize(objective2,lower,upper)
地块是
和
objective1(z)
和 objective2(z)
return NaN
在 z = 0
和其他地方的有限值,对某些 z > 0
有一个最佳值。
但是 results1
的输出是
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.010000, Inf]
* Minimizer: Inf
* Minimum: NaN
* Iterations: 1000
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): false
* Objective Function Calls: 1001
并且 results2
的输出是
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.010000, Inf]
* Minimizer: Inf
* Minimum: NaN
* Iterations: 1000
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): false
* Objective Function Calls: 1001
我认为问题出在 upper = Inf
。例如,如果我将其更改为 upper = 100
,results1
的输出为
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.010000, 100.000000]
* Minimizer: 1.000000e-02
* Minimum: 5.470728e-03
* Iterations: 55
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): true
* Objective Function Calls: 56
和results2
returns
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.010000, 100.000000]
* Minimizer: 1.000000e+02
* Minimum: -7.080863e+01
* Iterations: 36
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): true
* Objective Function Calls: 37
符合预期。
正如您在问题中指出的那样 - 您使用 有界优化 算法,但您向其传递了一个无界间隔。
引用文档 (https://julianlsolvers.github.io/Optim.jl/latest/#user/minimization/),optimize
函数是用于最小化有界区间上的单变量函数。
更详细地说明您遇到的问题。 optimize
方法搜索区间内的点。实现了两种算法:布伦特(默认)和黄金分割。他们首先检查的点是:
new_minimizer = x_lower + golden_ratio*(x_upper-x_lower)
你看到它 new_minimizer
将是 Inf
。因此优化程序甚至无法找到有效的内点。然后你看到你的函数 return NaN
for Inf
argument:
julia> objective1(Inf)
NaN
julia> objective2(Inf)
NaN
这个组合可以解释为什么在生成的输出中找到的最小值是 Inf
而 objective 是 NaN
。
第二点是你要记住Float64
数的精度是有限的,所以你应该选择区间,以确保该方法实际上能够准确地评估objective 在里面。例如,即使这样也失败了:
julia> optimize(objective1, 0.0001, 1.0e308)
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.000100, 100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000]
* Minimizer: 1.000005e+308
* Minimum: -Inf
* Iterations: 1000
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): false
* Objective Function Calls: 1001
原因是 objective1
对于非常大的参数(因为它具有有限的精度)实际上开始以数值不稳定的方式表现,参见:
julia> objective1(1.0e307)
7.2166623555e306
julia> objective1(1.0e308)
-Inf
最后一点是实际上 Optimize
告诉你出了点问题,你不应该依赖结果:
julia> results1.converged
false
julia> results2.converged
false
对于问题的初步说明(with Inf
)。
以下是说明我的问题的独立示例。
using Optim
χI = 3
ψI = 0.5
ϕI(z) = z^-ψI
λ = 1.0532733
V0 = 0.8522423425
zE = 0.5986
wRD = 0.72166623555
objective1(z) = -(z * χI * ϕI(z + zE) * (λ-1) * V0 - z * ( wRD ))
objective2(z) = -1 * objective1(z)
lower = 0.01
upper = Inf
plot(0:0.01:0.1,objective1,title = "objective1")
png("/home/nico/Desktop/objective1.png")
plot(0:0.01:0.1,objective2, title = "objective2")
png("/home/nico/Desktop/objective2.png")
results1 = optimize(objective1,lower,upper)
results2 = optimize(objective2,lower,upper)
地块是
和
objective1(z)
和 objective2(z)
return NaN
在 z = 0
和其他地方的有限值,对某些 z > 0
有一个最佳值。
但是 results1
的输出是
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.010000, Inf]
* Minimizer: Inf
* Minimum: NaN
* Iterations: 1000
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): false
* Objective Function Calls: 1001
并且 results2
的输出是
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.010000, Inf]
* Minimizer: Inf
* Minimum: NaN
* Iterations: 1000
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): false
* Objective Function Calls: 1001
我认为问题出在 upper = Inf
。例如,如果我将其更改为 upper = 100
,results1
的输出为
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.010000, 100.000000]
* Minimizer: 1.000000e-02
* Minimum: 5.470728e-03
* Iterations: 55
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): true
* Objective Function Calls: 56
和results2
returns
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.010000, 100.000000]
* Minimizer: 1.000000e+02
* Minimum: -7.080863e+01
* Iterations: 36
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): true
* Objective Function Calls: 37
符合预期。
正如您在问题中指出的那样 - 您使用 有界优化 算法,但您向其传递了一个无界间隔。
引用文档 (https://julianlsolvers.github.io/Optim.jl/latest/#user/minimization/),optimize
函数是用于最小化有界区间上的单变量函数。
更详细地说明您遇到的问题。 optimize
方法搜索区间内的点。实现了两种算法:布伦特(默认)和黄金分割。他们首先检查的点是:
new_minimizer = x_lower + golden_ratio*(x_upper-x_lower)
你看到它 new_minimizer
将是 Inf
。因此优化程序甚至无法找到有效的内点。然后你看到你的函数 return NaN
for Inf
argument:
julia> objective1(Inf)
NaN
julia> objective2(Inf)
NaN
这个组合可以解释为什么在生成的输出中找到的最小值是 Inf
而 objective 是 NaN
。
第二点是你要记住Float64
数的精度是有限的,所以你应该选择区间,以确保该方法实际上能够准确地评估objective 在里面。例如,即使这样也失败了:
julia> optimize(objective1, 0.0001, 1.0e308)
Results of Optimization Algorithm
* Algorithm: Brent's Method
* Search Interval: [0.000100, 100000000000000001097906362944045541740492309677311846336810682903157585404911491537163328978494688899061249669721172515611590283743140088328307009198146046031271664502933027185697489699588559043338384466165001178426897626212945177628091195786707458122783970171784415105291802893207873272974885715430223118336.000000]
* Minimizer: 1.000005e+308
* Minimum: -Inf
* Iterations: 1000
* Convergence: max(|x - x_upper|, |x - x_lower|) <= 2*(1.5e-08*|x|+2.2e-16): false
* Objective Function Calls: 1001
原因是 objective1
对于非常大的参数(因为它具有有限的精度)实际上开始以数值不稳定的方式表现,参见:
julia> objective1(1.0e307)
7.2166623555e306
julia> objective1(1.0e308)
-Inf
最后一点是实际上 Optimize
告诉你出了点问题,你不应该依赖结果:
julia> results1.converged
false
julia> results2.converged
false
对于问题的初步说明(with Inf
)。