如何解决如何找到非线性函数等于零的点
def alpha(t,ad):
if t < 0:
return 0
else:
return pow(ad,2) * t * np.exp(-1 * ad * t)
使用ad = 2
时,它从x = 0
上升到0.7
,并在0
处靠近x=3
。
我可以通过间隔进行迭代来查找此函数何时接近或等于0。但是我只需要知道函数接近或等于0的位置即可。我想知道是否有任何方法可以找到它而无需迭代ex)与x = 0函数相交,或者导数等于0 ...
解决方法
我假定您要查找导数等于零的时间。您可以使用sympy做到这一点:
In [12]: from sympy import exp,Symbol,nsolve
In [13]: ad = 2
In [14]: t = Symbol('t')
In [15]: f = pow(ad,2) * t * exp(-1 * ad * t)
In [16]: f
Out[16]:
-2⋅t
4⋅t⋅ℯ
In [17]: f.diff(t)
Out[17]:
-2⋅t -2⋅t
- 8⋅t⋅ℯ + 4⋅ℯ
In [18]: solve(f.diff(t),t)
Out[18]: [1/2]
编辑:您在下面的答案提出了与OP中的问题不同的问题,因此我将对此进行更新:
您想找到这个零点:
In [5]: ad = Symbol('ad')
In [6]: t = Symbol('t')
In [7]: epsilon = Symbol('epsilon')
In [8]: f = pow(ad,2) * t * exp(-1 * ad * t) - epsilon
In [9]: f
Out[9]:
2 -ad⋅t
ad ⋅t⋅ℯ - ε
我们可以使用solve
来解析地解决这个问题:
In [10]: sol,= solve(f,t)
In [11]: sol
Out[11]:
⎛-ε ⎞
-W⎜───⎟
⎝ ad⎠
────────
ad
此答案是根据Lambert W函数给出的。您可以替换ad
和epsilon
以获得任何特定值的答案:
In [12]: sol.subs({ad:2,epsilon:0.01})
Out[12]: 0.00251259459155665
尽管它是Lambert W函数的分支W0,但它却使根接近零。另一个根由分支W_{-1}
给出,并且是
In [32]: -LambertW(-epsilon/ad,-1)/ad
Out[32]:
⎛-ε ⎞
-W⎜───,-1⎟
⎝ ad ⎠
────────────
ad
In [28]: (-LambertW(-epsilon/ad,-1)/ad).subs({ad:2,epsilon:0.01}).n()
Out[28]: 3.64199856754954
如果您只想用数字方法求解这些,则可以使用nsolve
:
In [29]: nsolve(f.subs({ad:2,epsilon:0.01}),t,0)
Out[29]: 0.00251259459155665
In [30]: nsolve(f.subs({ad:2,1)
Out[30]: 3.64199856754954
,
我能够使用Oscar的答案找到解决方案。
- 该函数是指数函数,因此它永远不会在0之后达到0
- 我只是用负的ε拉了一点功能 (epsilon是用户定义的)
- 会有两个零,我只需要第二个零。
from sympy import exp,solve
epsilon = 0.01
ad = 2
t = Symbol('t')
f = pow(ad,2) * t * exp(-1 * ad * t) - epsilon
print(solve([f],dict=True,quick=True))
#print(solve([t > 0,f],quick=True)) i get an error if i use this
但是,这种寻找接近零的x的解决方案所花的时间比仅在函数上按0.01
的间隔进行迭代要花费更多的时间。
from sympy import exp,solve,Piecewise
import numpy as np
epsilon = 0.01
ad = 2
t = Symbol('t')
f = pow(ad,2) * t * exp(-1 * ad * t) - epsilon
#print(solve([f],quick=True))
def alpha(t,ad):
if t < 0:
return 0
else:
return pow(ad,2) * t * np.exp(-1 * ad * t)
def find(function,farg,arange,epsilon):
xs = []
for x in arange:
if function(x,**farg) < epsilon:
xs.append(x)
return xs
if __name__ == "__main__":
import timeit
print(timeit.timeit("solve([f],dict=True)",setup="from __main__ import solve,f,t",number=100))
print(timeit.timeit("solve([f],quick=True)",number=100))
print(timeit.timeit("find(alpha,{'ad':ad},np.arange(0,4,0.01),0.01)",setup="from __main__ import find,alpha,ad,np",number=100))
输出
24.860103617
24.020882552
0.10911201300000073
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。