查找其中f(x)= 0的阈值 [英] Find threshold value where f(x)=0

查看:99
本文介绍了查找其中f(x)= 0的阈值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数f(x),对于x<c为正,并且递减,对于所有x>=c为零.如何找到c,即函数达到零(在公差范围内)的阈值?

I have a function f(x), that is positive and decreasing for x<c, and is zero for all x>=c. How can I find c, the threshold where the function hits zero (to within a tolerance)?

这是一个例子:

zer = function(x){
    ifelse(x>5, rep(0,length(x)), 5 - x)
}

> x=-5:15
> plot(x,zer(x))

您可以使用uniroot查找某个函数在零交叉处的位置,但这依赖于该函数在交叉的两边分别为负值和正值,因此我不能在这里使用它.在上述情况下,它以上限(15)计算zer,找到零,然后将其返回.

You can use uniroot to find where a function crosses zero, but that relies on the function being negative and positive on either side of the crossing, so I can't use that here. In the above case it evaluates zer at the upper interval (15), finds a zero, and returns that.

我编写了一个二等分算法,该算法从间隔开始,如果f(midpoint) == 0,则向左移动,如果f(midpoint) > 0,则向右移动.这行得通,但是我想知道我是否错过了一个软件包或其他地方的实现方案,而该实现方案做得更好,或者我是否错过了一个简单的技巧,可让您使用uniroot解决此问题".

I wrote a bisection algorithm that starts with the interval and moves left if f(midpoint) == 0 or right if f(midpoint) > 0. This works, but I'm wondering if I've missed an implementation in a package or elsewhere that does this better, or if I've missed "one simple trick that lets you use uniroot to solve this".

我能在文档中找到的最好的东西是数值任务视图的神秘之处:在某些贡献的软件包中都有对分算法的实现."

The best I can find in the docs is the Numerical Task View's cryptic "There are implementations of the bisection algorithm in several contributed packages."

请注意,我没有f(x)的渐变,所以不能使用牛顿法或任何需要在x值处进行渐变评估的东西.

Note I don't have the gradient of f(x) so can't use Newton's method or anything that needs gradient evaluations at x values.

推荐答案

此问题似乎非常适合平分方法.我们可以这样做,例如:

This problem seems to be well suited to a bisection method. We can do it something like this for example:

findroot = function(f, x, tol = 1e-9) {
  if (f(x[2]) > 0) stop("No root in range")
  if (f(x[1]) <= tol) return (x[1])
  else {
    xmid = mean(x)
    if(f(xmid) == 0) x = c(x[1], xmid) else x = c(xmid, x[2])
    return (findroot(f, x, tol))
  }
}

findroot(zer, range(x))
# [1] 5

这篇关于查找其中f(x)= 0的阈值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆