我试图计算tanh(x)的根作为练习。
我使用Newton-Raphson方法,算法要求初步猜测
算法假设对于大于约1的初始猜测不收敛。但是在得到它之前我得到了数学范围错误。
这是我使用
的代码from math import *
def f(x):#define the function
return tanh(x)
def fdiv(x):#define its derivative
return 4*(cosh(x))**2/(cosh(2*x)+1)**2
def Raphson(rx0):
return (rx0-f(rx0)/fdiv(rx0))#according to the Newton Raphson Method
def Q1_6_Raphson(rx0,Iter=1):
if Iter > 30:#maximum iterations allowed is 30
print("Newton Raphson Algorithim did not converge after 30 Trials, try other initial guesses")
return
elif fdiv(rx0)==0:
print("The initial guess you chose leads to diving by zero in the Newton-Raphson method. Choose another guess")
return
print(Iter, 'Newton-Raphson ' +str(rx0) +' error ' +str(rx0-(0)))
if rx0==0:
return
else:
return Q1_6_Raphson(Raphson(rx0),Iter=Iter+1) # call the function recursively
例如,当我尝试运行Q1_6Raphson(5)
时,我得到:
Traceback (most recent call last):
File "<pyshell#101>", line 1, in <module>
Q1_6_Raphson(5)
File "C:\Users\AsafHaddad\Documents\סמסטר 8\חישובית\Targil_3\Question1.6.py", line 40, in Q1_6_Raphson
return Q1_6_Raphson(Raphson(rx0),Iter=Iter+1) # call the function recursively
File "C:\Users\AsafHaddad\Documents\סמסטר 8\חישובית\Targil_3\Question1.6.py", line 33, in Q1_6_Raphson
elif fdiv(rx0)==0:
File "C:\Users\AsafHaddad\Documents\סמסטר 8\חישובית\Targil_3\Question1.6.py", line 21, in fdiv
return 4*(cosh(x))**2/(cosh(2*x)+1)**2
OverflowError: math range error
根据我的阅读,当数字太大时会发生数学范围错误。但我不明白的是,我的代码中调用的每个函数都可以使用5作为输入:
>>> f(5)
0.9999092042625951
>>> fdiv(5)
0.00018158323094380672
>>> Raphson(5)
-5501.616437351696
那么问题是什么?什么触发了数学范围错误?
答案 0 :(得分:1)
Raphson(5)
来电会返回一个较大的负数:
>>> Raphson(5)
-5501.616437351696
将其传递给递归调用:
return Q1_6_Raphson(Raphson(rx0),Iter=Iter+1)
因此使用Q1_6_Raphson()
作为-5501.616437351696
参数调用rx0
。然后将其传递给fdiv()
:
elif fdiv(rx0)==0:
抛出异常,因为该数字大于math.cosh()
可以处理的数字:
>>> fdiv(-5501.616437351696)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fdiv
OverflowError: math range error
超出范围[-710,+ 710]的任何值都会抛出该异常;在这个范围内你会得到一个不同的例外:
>>> fdiv(-710)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in fdiv
OverflowError: (34, 'Result too large')
因为您仍然超出了平台浮点支持的限制。
只有[-177,+ 177]范围内的值才会给出结果。
答案 1 :(得分:0)
长评:请您详细说明您是如何获得衍生产品的?通过导数的商公式的正常方法只是简单地
d/dx tanh(x)=(cosh(x)**2-sinh(x)**2)/cosh(x)**2
=1-tanh(x)**2 or
=1/cosh(x)**2
自
cosh(2x)=cosh(x)**2+sinh(x)**2=2*cosh(x)**2-1,
您的衍生金额
4*(cosh(x))**2/(cosh(2*x)+1)**2 = 1/cosh(x)**2
因此它给出了正确的结果,但却是一个不必要的复杂公式。
注意:在这个特定情况下,牛顿迭代可以简化为
xnext = x - 0.5*sinh(2*x)
这个的衍生物是
d(xnext)/ dx = 1 - cosh(2 * x)= -2 * sinh(x)** 2
因此,收缩性域由cosh(2 * x)<2定义,相当于
|x|<0.5*ln(2+sqrt(3))=ln(1+sqrt(3))-0.5*ln(2)