我查看了uniroot和optimize的描述,但它们有些不同,但书籍参考是一样的,我想知道是否有理由选择一个而不是另一个?
答案 0 :(得分:8)
至于理由选择一个而不是另一个。在(可能)大多数情况下,一个人会更自然。正如@shadow所说,optimise
用于最小化(或最大化),uniroot
用于找到零点。
在某些情况下,您可以使用其中任何一种来解决问题。这通常是因为你可以采取衍生工具,但可能还有另一种方法来重构你的问题。本答案的其余部分将讨论这些案例,您实际上可以选择并需要在两种情况之间进行选择。
对于一个简单的例子,我们可能想要找到函数的最小值:
Func = function(x) {
(2*x-pi)^2 + exp(1)*x - 18
}
执行此操作的一种方法是将optimize
用作:
OResult = optimize(Func, lower = 0, upper = 5)
OResult
$minimum
[1] 1.231011
$objective
[1] -14.19195
另一种方法是通过取导数来转换函数。由于最佳点是当导数为零时,我们需要像uniroot这样的寻根算法。因此功能变为:
DerivFunction = function(x) {
4*(2*x-pi) + exp(1)
}
通过以下方式优化:
UResult = uniroot(DerivFunction , interval = c(0,5))
UResult
$root
[1] 1.231011
$f.root
[1] 4.440892e-16
$iter
[1] 2
$init.it
[1] NA
$estim.prec
[1] 6.103516e-05
如果您在上述方法之间做出选择,那么为了简单起见,您可能会使用optimize
。但有些情况下uniroot
可能会更快。
使用上面的例子,optimize
函数调用函数7次,而uniroot只调用衍生函数5次。 (这可以通过将计数器放在上面的函数中找到)。这是合乎逻辑的,优化不知道最小值有多低,而uniroot确实知道目标函数值为零。因此,uniroot通常会知道x轴的方向,而优化则需要更多地查看。
如果我们做基准测试,那么优化速度要快得多。
所以一般来说(如果你正在考虑速度)使用优化,除非它是一个非常密集的函数,其中函数调用比优化算法正在做的更昂贵(当然在这些情况下,通常很难得到一种形式的使用uniroot
的问题。)
library(microbenchmark)
microbenchmark(
optimize(Func, lower = 0, upper = 5),
uniroot(DerivFunction, interval = c(0,5))
)
Unit: microseconds
expr min lq mean median uq max neval
optimize(Func, lower = 0, upper = 5) 18.264 19.785 23.50664 20.7370 23.781 129.365 100
uniroot(DerivFunction, interval = c(0, 5)) 63.161 67.346 74.10322 69.8195 76.858 143.062 100
优化函数可能找不到全局最优,而只是局部最优。同样适用于uniroot
,它可能会找到局部零但不存在其他零。 uniroot
与optimize
不同,但是当您设置优化以查找最大值或最小值时,uniroot
会找到一个与y轴相交的点。如果你uniroot
得到一个导数,那么这个点可能是最小值或最大值。
例如,如果我们有以下功能和派生词:
TwoMinFunction = function(x){
((x)^4)/4 + x^3 - 3*x^2 - 8*x + 16
}
TwoZeroDerivFunction = function(x){
(x^3 + 3*x^2 − 6*x − 8)
}
此功能如下图所示:
OResult = optimize(TwoMinFunction, lower = -6, upper = 4)
OResult
$minimum
[1] -4.000001
$objective
[1] 8.007817e-12
UResult = uniroot(TwoZeroDerivFunction , interval = c(-6,4))
UResult
$root
[1] -1
$f.root
[1] 0
$iter
[1] 1
$init.it
[1] NA
$estim.prec
[1] 5
这里发生的事情是优化找到了两个最小值中的一个。另一方面,uniroot功能发现了一个最大值(因为uniroot不能区分最小值和最大值)。
答案 1 :(得分:6)
这两个功能的用途完全不同:
optimize
用于查找函数的最小值(或最大值)。
uniroot
用于查找函数的根(零)。