R **优化**和**单根**之间有什么区别?

R **优化**和**单根**之间有什么区别?,r,R,我查看了uniroot和optimize的描述,它们有些不同,但参考书是相同的,我想知道是否有理由选择其中一个而不是另一个?这两个函数有完全不同的用途: optimize用于查找函数的最小值(或最大值) uniroot用于查找函数的根(零) 至于选择一个而不是另一个的原因。在(可能)大多数情况下,人们会更自然。正如@shadow所说,optimize用于最小化(或最大化),uniroot用于寻找零点 但是,在某些情况下,您可以使用这两种方法来解决您的问题。这通常是因为你可以使用衍生工具,但也可

我查看了uniroot和optimize的描述,它们有些不同,但参考书是相同的,我想知道是否有理由选择其中一个而不是另一个?

这两个函数有完全不同的用途:

  • optimize
    用于查找函数的最小值(或最大值)

  • uniroot
    用于查找函数的根(零)


至于选择一个而不是另一个的原因。在(可能)大多数情况下,人们会更自然。正如@shadow所说,
optimize
用于最小化(或最大化),
uniroot
用于寻找零点

但是,在某些情况下,您可以使用这两种方法来解决您的问题。这通常是因为你可以使用衍生工具,但也可能有其他方法来重组你的问题。这个答案的其余部分将讨论这些情况,在这些情况下,您实际上有一个选择,需要在这两种情况中进行选择

对于一个简单的例子,我们可能希望找到函数的最小值:

Func = function(x) {
  (2*x-pi)^2 + exp(1)*x - 18
}
一种方法是使用
优化
作为:

OResult = optimize(Func, lower = 0, upper = 5)
OResult
$minimum
[1] 1.231011

$objective
[1] -14.19195
另一种方法是通过求导数来变换函数。由于最佳点是导数为零时,我们需要一个类似于单根的寻根算法。因此,函数变成:

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次。(这可以通过在上述函数中放置计数器来找到)。这是合乎逻辑的,optimize不知道最小值有多低,而uniroot知道将函数值设定为零。因此,uniroot通常知道x轴的方向,而optimize需要更多地查看

但是,如果我们进行基准优化,速度会快得多。 因此,通常(如果您关注速度)使用optimize,除非它是一个非常密集的函数,其中函数调用比优化算法所做的要昂贵(当然,在这些情况下,通常很难找到问题的一种形式来使用
uniroot

多重局部最优 优化函数可能找不到全局最优解,而仅仅是局部最优解。对于
uniroot
,情况也是如此,它可能会找到一个局部零,但不会找到其他存在的零
uniroot
optimize
不同,但是当您将optimize设置为查找最大值或最小值时,
uniroot
将查找一个与y轴相交的点。如果你对一个导数使用单根,那么这个点可以是一个极小值或极大值

例如,如果我们有以下函数和导数:

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) 
}
该功能如下图所示:


这里发生的是优化找到了两个极小值中的一个。另一方面,uniroot函数发现了一个最大值(因为uniroot无法区分最小值和最大值)。

的描述部分可能会给您一些关于它们之间的区别的提示。我反对这个答案,因为虽然这是一个很小的区别,但答案并没有触及OPs问题的核心。根查找通常可以重新表示为优化。只有当f(左端点)与f(右端点)是不同的符号时,Uniroot才起作用。这不是优化所必需的。Optimize可用于在unitroot失败时查找根,例如
uniroot(f=function(x){x^2-4},interval=c(-10,10))
vs
Optimize(f=function(x){(x^2-5)^2},interval=c(-10,10))
。您可以检查来自optimize的答案是否是$ObjectiveForMe的根,uniroot不提供此类信息,它只给出错误消息“端点处的f()值不是相反的符号”,它没有指定关于多个根的任何内容。例如,
uniroot(f=function(x){x*(x^2-4)},interval=c(-10,10))
只找到一个根,尽管有多个根。所以,也许我遗漏了一些你们正在讨论的论点。
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